当前位置: 首页 > 面试题库 >

Hibernate和@JoinFormula:org.hibernate.mapping.Formula无法转换为org.hibernate.mapping.Column

邓威
2023-03-14
问题内容

我正在尝试为旧的数据库架构编写一个hibernate适配器。该模式没有专用的id列,但是使用了大约三列来连接数据。

在某些表上,我需要使用合并。到目前为止,这是我想出的:

关于定义:

  • 汽车可以具有由汽车用户或汽车用户组分配的元素。
  • 如果FORIGN_ELEMENT持有用户名,则定义为’u’
  • 如果FORIGN_ELEMENT持有组名,则定义为’g’
  • 这也意味着滥用了一个表(CAR_TO_ELEMENT)将汽车映射到元素,并将汽车组映射到元素。我定义了一个超类CarElement并将其子类CarUserElement和CarGroupElement组成。
  • 状态为“活动”或无趣的字符串
  • 我在其他地方设置了定义并声明状态,我们不必为此担心。
  • 在联接表上使用DEP_NR。如果为零,请使用USR_DEP_NR。我在本COALESCE(NULLIF())机SQL中成功地做到了这一点,并希望在Hibernate中使用Pojos实现相同的目的。

好的,下面是代码

@Entity
@Table(name="CAR")
public class Car extends TableEntry implements Serializable {
    @Id
    @Column(name="DEP_NR")
    private int depnr;

    @Id
    @Column(name="USER_NAME")
    @Type(type="TrimmedString")
    private String username;

    @ManyToOne(fetch = FetchType.EAGER, targetEntity=CarGroup.class)
    @JoinColumns(value={ 
            @JoinColumn(name="GROUP_NAME"),
            @JoinColumn(name="DEP_NR"),
            @JoinColumn(name="state"),
    })
    private CarGroup group;

    @OneToMany(fetch=FetchType.EAGER, targetEntity=CarUserElement.class, mappedBy="car")
    private Set<CarUserElement> elements;
}



@Entity
@Table(name="CAR_GROUP")
public class CarGroup extends TableEntry implements Serializable {
    @Id
    @Column(name="DEP_NR")
    private int depnr;

    @Id
    @Column(name="GROUP_NAME")
    @Type(type="TrimmedString")
    private String group;

    @ManyToOne(fetch = FetchType.EAGER, targetEntity=Car.class)
    @JoinColumns(value={ 
            @JoinColumn(name="GROUP_NAME"),
            @JoinColumn(name="DEP_NR"),
            @JoinColumn(name="state"),
    })
    private Set<Car> cars;

    @OneToMany(fetch=FetchType.EAGER, targetEntity=CarGroupElement.class, mappedBy="car")
    private Set<CarGroupElement> elements;
}



@MappedSuperclass
public class CarElement extends TableEntry {
    @Id
    @ManyToOne(fetch = FetchType.EAGER, targetEntity=Element.class)
    @JoinColumns(value={ 
            @JoinColumn(name="ELEMENT_NAME"),
            @JoinColumn(name="state"),
    })
    private Element element;
}



@Entity
@Table(name="CAR_TO_ELEMENT")
public class CarUserElement extends CarElement {
    @Id
    @Column(name="DEFINITION")
    private char definition;

    @Id
    @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")),
        @JoinColumnOrFormula(column=@JoinColumn(name="STATE", referencedColumnName="STATE"))
    })
    private Car car;

}



@Entity
@Table(name="CAR_TO_ELEMENT")
public class CarGroupElement extends CarElement {
    @Id
    @Column(name="DEFINITION")
    private char definition;

    @Id
    @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="GROUP_NAME")),
        @JoinColumnOrFormula(column=@JoinColumn(name="STATE", referencedColumnName="STATE"))
    })
    private Car car;

}

我尝试了所有可用的hibernate版本(从3.5.1
[带@JoinColumnsOrFormulas]的第一个版本到4.xx),但是我总是收到此错误:

Exception in thread "main" java.lang.ClassCastException: org.hibernate.mapping.Formula cannot be cast to org.hibernate.mapping.Column
    at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:351)
    at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1338)
    at org.hibernate.cfg.annotations.html" target="_blank">CollectionBinder.bindOneToManySecondPass(CollectionBinder.java:791)
    at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:719)
    at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:668)
    at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:66)
    at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1597)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1355)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1737)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1788)

其他hibernate用户似乎也有相同的问题:他们无法在任何版本上使用它,请参见此线程和其他stackoverflow问题:https
:
//forum.hibernate.org/viewtopic.php?
f =1& t
=1010559

为了更完整,这是我的TrimmedString类:https
://forum.hibernate.org/viewtopic.php
?
p
=
2191674
&
sid
=
049b85950db50a8bd145f9dac49a5f6e#p2191674

提前致谢!

PS:它仅通过一个DEP-NR-Column(即,仅使用@JoinColumns使用DEP_NR
USR_DEP_NR)就可以将这三个库伦加入到一起。但是我需要这个coalesce(nullif())


问题答案:

暂时,联接公式在Hibernate中非常脆弱。我一直很难让他们正常工作。

通常,对我有用的解决方法是创建数据库视图,以显示适当的列(包括原始表中不存在的外键)。然后,我使用分类Hibernate / JPA映射将实体映射到视图。

有时,使用此类实体时,生成的SQL中会有多余的联接,但是在大多数情况下,数据库会优化此类查询,因此无论如何执行计划都是最佳的。

另一种方法可能是使用@Subselects,这是某种Hibernate视图,但是我希望它们的性能不如经典数据库视图。



 类似资料:
  • 问题内容: 好的,当我开始一个新的Java项目并集成诸如spring / hibernate之类的工具时,我是一个完全的初学者。实际上,这是我第一次这样做。因此,我敢肯定错误对于你们来说将是显而易见的。 猜测: 我期望的会话工厂不是春天注入的。 错误的依赖关系。 错误 pom.xml base-context.xml hibernate-context.xml hibernate.properti

  • 问题内容: 为什么写: 问题答案: 实现的对象是。 您要在其中覆盖的方法应将对象作为参数,而将其强制转换为。您的实现应描述如何与另一个进行比较。 要真正进行排序,您可能还需要制作工具,然后将实际逻辑复制粘贴到其中。

  • 问题内容: 我当前正在使用条件来检索用户的详细信息,但是当尝试用合适的用户查询详细信息对象时,我得到了ClassCastException。 我的标准代码; 我也尝试使用; 两者都给我ClassCastException。我知道我可以通过让用户实现Serializable来轻松解决它,但是还有其他解决方案吗? 问题答案: 唯一的其他解决方案是实现Externalizable。

  • 问题内容: 我已经编写了一个通用类,下面是该类的构造函数。我想像这样写 由于我不知道运行时的泛型类型,因此它将引发异常。 有什么办法解决这些问题?E的声明是 这就是我要打电话的方式 更新 家伙,谢谢您的帮助。我在搞泛型,所以问题就被创建了。这是所有导致问题的代码- 更新2 :似乎除了传递下面的答案中提到的类类型外,我们无法做到这一点。 问题答案: 这是重现异常所需的最最少的代码。 Java泛型使用

  • 问题内容: 在我的应用程序中,我为gcm ccs(xmpp)运行这些代码,并且代码显示以下错误执行时发生错误 这是代码: 问题答案: 您如何申报?我想它是简单的,如果是这样,请将其更改为: 此异常的原因与以下代码中发生的原因类似: Java中的VarArgs是作为数组实现的,因此,当您将sendTask声明为as时,编译器将使用with进行调用,但是当您将then 声明为then 时,则将使用wi

  • 问题内容: 我的程序看起来像 数据看起来像 在运行该程序时,我在控制台上看到以下内容 我相信Class Types是正确映射的, Class Mapper , 请让我知道我在这里做错了什么吗? 问题答案: 当您使用M / R程序读取文件时,映射器的输入键应为 文件中该行的索引 ,而输入值将为整行。 因此,这里正在发生的事情是您试图将行索引作为错误的对象,并且您需要一个替代项,以便Hadoop不会抱