使用 H2、JPA 注释和 Hibernate 问题的一对多关联

Posted

技术标签:

【中文标题】使用 H2、JPA 注释和 Hibernate 问题的一对多关联【英文标题】:Using One-to-Many associations with H2, JPA annotations and Hibernate Problem 【发布时间】:2011-09-26 15:02:00 【问题描述】:

我们使用 H2、JPA 注释、Spring 和 Hibernate 的组合来开发我们的 web 应用程序。我们在 MODE=Oracle 的兼容模式下使用 H2。

我们有一个与 ItSystemAka 类具有一对多关联的 ItSystem 类,如下所示:

@Entity 
@Table(name="ITSYSTEM") 
public class ItSystem implements Serializable  
    private static final long serialVersionUID = 1L; 
    private static final String SEQ_NAME = "SeqName"; 
    private static final String SEQUENCE = "sequence"; 

    @Id 
    @GeneratedValue(generator = SEQ_NAME) 
    @GenericGenerator(name = SEQ_NAME,strategy = SEQUENCE, parameters =  @Parameter(name = SEQUENCE, value = "IT_SYSTEM_SEQ") ) 
    @Column(name="ITSYSTEM_EDW_ID") 
    private BigDecimal itSystemEdwId; 

    @Column(name="ITSYSTEM_VERSION_ID") 
    private BigDecimal itSystemVersionId; 

    @OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL) 
    @JoinColumn(name="ITSYSTEM_EDW_ID") 
    private Set<ItsystemAka> itSystemAkas; 

    ..... 


@Entity 
@Table(name="ITSYSTEM_AKA") 
public class ItSystemAka implements Serializable  
    private static final long serialVersionUID = 1L; 
    private static final String SEQ_NAME = "SeqName"; 
    private static final String SEQUENCE = "sequence"; 

    @Id 
    @GeneratedValue(generator = SEQ_NAME) 
    @GenericGenerator(name = SEQ_NAME,strategy = SEQUENCE, parameters =  @Parameter(name = SEQUENCE, value = "IT_SYSTEM_AKA_SEQ") ) 
    @Column(name="AKA_EDW_ID") 
    private BigDecimal akaEdwId; 

    private String aka; 

    @Column(name="ITSYSTEM_EDW_ID") 
    private BigDecimal itSystemEdwId; 

    .... 

我们正在使用以下连接属性:

myDataSource.driverClassName=org.h2.Driver 
myDataSource.url=jdbc:h2:~/test;MODE=Oracle;DB_CLOSE_DELAY=-1 
myDataSource.username=sa 
myDataSource.password= 
sessionFactory.hibernateProperties[hibernate.dialect]=org.hibernate.dialect­.H2Dialect 
sessionFactory.hibernateProperties[hibernate.hbm2ddl.auto]=create 
sessionFactory.hibernateProperties[hibernate.show_sql]=false 
sessionFactory.hibernateProperties[hibernate.connection.autocommit]=false 
sessionFactory.hibernateProperties[hibernate.format_sql]=true 

如果我们有一个带有多个 ItSystemAka 实例的 ItSystem 实例,并且我们尝试将 ItSystem 实例更新到数据库中,那么它将丢失对所有关联 ItSystemAkas 的引用。使用 H2 控制台查看数据库,我可以看到 中相应行的外键 (IT_SYSTEM_EDW_ID) ITSYSTEM_AKA 表被设置为空。

按照 H2 网站上的建议,我尝试使用 Oracle 方言而不是本地 H2 方言,但它产生了相同的结果。我还尝试使用实际的 Oracle 数据库而不是 H2,在这种情况下一切似乎都正常。

你知道出了什么问题吗?

任何帮助将不胜感激。

问候, 普里耶什

【问题讨论】:

【参考方案1】:

在这种情况下,方言无关紧要。

如果使用此映射,则表之间存在单向关系。 像这样重新组织映射的简单方法

@Entity 
@Table(name="ITSYSTEM") 
public class ItSystem implements Serializable  
   ....
   @Id 
   @GeneratedValue(generator = SEQ_NAME) 
   @GenericGenerator(name = SEQ_NAME,strategy = SEQUENCE, parameters =  @Parameter(name = SEQUENCE, value = "IT_SYSTEM_SEQ") ) 
   @Column(name="ITSYSTEM_EDW_ID") 
   private BigDecimal itSystemEdwId;  

   @OneToMany(fetch = FetchType.EAGER, mappedBy="itSystemEdwId", cascade=CascadeType.ALL) 
   private Set<ItsystemAka> itSystemAkas; 
   ..... 


@Entity 
@Table(name="ITSYSTEM_AKA") 
public class ItSystemAka implements Serializable  
   ... 

   @Id 
   @GeneratedValue(generator = SEQ_NAME) 
   @GenericGenerator(name = SEQ_NAME,strategy = SEQUENCE, parameters =  @Parameter(name = SEQUENCE, value = "IT_SYSTEM_AKA_SEQ") ) 
   @Column(name="AKA_EDW_ID") 
   private BigDecimal akaEdwId; 
   ...
   @Parent
   private ItSystem itSystemEdwId; 
   .... 

mappedBy 总是创建双向关系

【讨论】:

这可行,但是我们希望能够使用单向的一对多关联。我仍然不明白为什么对具有单向一对多关联的实体的更新适用于 Oracle,但不适用于 H2。问候,普里耶什 首先,如果您尝试映射@Column(name="ITSYSTEM_EDW_ID") private BigDecimal itSystemEdwId; 您尝试将您的关联设为双向。

以上是关于使用 H2、JPA 注释和 Hibernate 问题的一对多关联的主要内容,如果未能解决你的问题,请参考以下文章

如何使用hibernate jpa在内存数据库中设置h2?

要使用的Hibernate或JPA注释

Hibernate JPA H2 问题中的“限制”列

如何将继承策略与 JPA 注释和 Hibernate 混合使用?

无法使用 JPA 在 H2 中创建表和加载数据

Hibernate @LazyToOne 注释的 JPA 等价物是啥?