Hibernate and @JoinFormula: org.hibernate.mapping.Formula cannot be cast to org.hibernate.mapping.Column

后端 未结 3 796
攒了一身酷
攒了一身酷 2020-12-17 09:36

I\'m trying to write a hibernate adapter for an old database schema. This schema does not have a dedicated id column, but uses about three other columns to join data.

<
相关标签:
3条回答
  • 2020-12-17 10:22

    Join formulas are very fragile in Hibernate for the time being; I always had a difficult time to get them work properly.

    The workaround that helped me often was to create database views which exposed the proper columns (including foreign keys that don't exist in the original tables). Then I mapped the entities to the views using classing Hibernate/JPA mappings.

    Sometimes there are redundant joins in the generated SQL when using such entities, but the database optimizes such queries in most cases so that the execution plan is optimal anyway.

    Another approach could be using @Subselects, which are some kind of Hibernate views, but I expect them to be less performant than the classic database views.

    0 讨论(0)
  • 2020-12-17 10:22

    I ran into a similar problem, and it seems that the issue is that you are using a @Formula inside an @Id. Hibernate wants Ids to be insertable, and Formulas are read-only.

    In my case I was able to work around the problem by making the individual columns Id properties on their own, and making the joined object a separate property. I don't know if this would work in your case since you're using two different columns in your formula, but if so your code might look something like:

    @Entity
    @Table(name="CAR_TO_ELEMENT")
    public class CarUserElement extends CarElement {
        @Id
        @Column(name="DEFINITION")
        private char definition;
    
        @Id
        @Column(name="DEP_NR")
        private Integer depNr;
    
        @Id
        @Column(name="USR_DEP_NR")
        private Integer usrDepNr;
    
        @Id
        @Column(name="FORIGN_ELEMENT")
        private String userName;
    
        @Id
        @Column(name="STATE")
        private String state;
    
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumnsOrFormulas(value = {
            @JoinColumnOrFormula(formula=@JoinFormula(value="COALESCE(NULLIF(DEP_NR, 0), USR_DEP_NR)", referencedColumnName="DEP_NR")),
            @JoinColumnOrFormula(column=@JoinColumn(name="FORIGN_ELEMENT", referencedColumnName="USER_NAME", insertable = false, updatable = false)),
            @JoinColumnOrFormula(column=@JoinColumn(name="STATE", referencedColumnName="STATE", insertable = false, updatable = false))
        })
        private Car car;
    
    }
    
    0 讨论(0)
  • 2020-12-17 10:25

    I ran into the cast exception as well and I'm on Hibernate 5.x.

    Until Hibernate dedicates time to fix the issue, I found that while this guy's approach may not be cleanest (he even eludes to that fact!), it works.

    You just need to add the @Column mappings (and get/set methods) to your association table objects that are returning null and manually set the values when you populate the relation data. Simple but effective!

    0 讨论(0)
提交回复
热议问题