【问题标题】:Multiple 1:many relationship in HibernateHibernate中的多1:多关系
【发布时间】:2012-06-25 11:51:39
【问题描述】:

如何为同一个实体配置多个一对多关系?

考虑两个类 Boy 和 Toy。它们如下图所示

class Boy {
    @OneToMany(mappedBy='ownedBy',fetch=FetchType.EAGER, cascade=CascadeType.ALL)
    private List<Toy> bikes;
    ...
    @OneToMany(mappedBy='ownedBy',fetch=FetchType.EAGER, cascade=CascadeType.ALL)
    private List<Toy> cars;
    ...

class Toy {
    @ManyToOne
    private Boy ownedBy;
    ...

我知道这个配置是错误的。但是我不知道这里需要配置什么。 两边的@OneToMany@ManyToOne注解应该怎么配置?

在将“mappedBy”添加到注释之前,我收到了以下异常消息

java.sql.SQLException: Field 'cars_Id' doesn't have a default value
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2683)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2144)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2444)
    at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1997)

但是当注释中没有添加“mappedBy”时,创建了一个像“boy_toy”这样的连接表。添加后我没有看到在数据库中创建的表。

  • 更新

boy_toy 表也有三列,即 boy_id、cars_id 和 bikes_id。但理想情况下,它应该像 boy_id 一个 not null 和其他可为空的列。但是生成的所有列都不可为空。我试图从注释中删除“mappedBy”并手动编辑表结构以使cars_id 和bikes_id 可以为空。它就像一个奇迹。

所以现在,我唯一剩下的问题是

我们如何让 hibernate 配置一个包含可空和不可空列的连接表?

【问题讨论】:

  • 您的映射没有意义,为什么要为相同的项目创建两个集合?如果要针对同一类型进行多个映射,则需要为它们指定唯一的 mappedBy。换句话说,你不能通过“ownedBy”来映射两个集合,Hibernate 不知道该怎么做,尤其是在合并/持久化的情况下。
  • 其实我没有任何要求。我刚刚对hibernate做了一些实验。我了解到“mappedBy”并不能解决问题。删除“mappedBy”创建了一个包含 BOY_ID、BIKES_ID 和 CARS_ID 列的连接表 BOY_TOY;所有这些都不可为空。我想知道一种方法,它会告诉休眠使 BIKES_ID 和 CARS_ID 可以为空字段。

标签: hibernate orm mapping one-to-many


【解决方案1】:

使用继承,在BOY和TOY之间建立1-N关系,采用继承策略SINGLE_TABLE。要仅检索连接到 Boy 的 Bikes 或 Cars,请使用多态查询。

奖励:即使自行车和汽车是不同的类别,上述设置也不起作用。原因是,您不能使用 fetch=FetchType.EAGER 建立多个 1-N 关系。在我的博客中了解更多信息:MultipleBagFetchException and Java equality

编辑:多态查询

简单:

entityManager.createQuery("SELECT toy FROM Toy toy"); // 返回所有 Toy 实例,无论是自行车还是汽车

entityManager.createQuery("SELECT bike FROM Bike bike"); // 只返回 Bike 类型的玩具实例

在上述表达式中,您显然可以使用所有其他 JPQL 构造,例如 WHERE、连接等。

如果您碰巧使用 JPA2.0,则有一些关于多态性的新功能,例如类型检查和类型转换,请参见此处:http://wiki.eclipse.org/EclipseLink/Release/2.1.0/JPAQueryEnhancements

【讨论】:

  • 如果您能指出一些关于多态查询的文章,那就太好了。
猜你喜欢
  • 1970-01-01
  • 2013-11-19
  • 1970-01-01
  • 1970-01-01
  • 2011-09-30
  • 1970-01-01
  • 2014-11-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多