Использование ассоциаций «один ко многим» с аннотациями H2, JPA и проблемой Hibernate

Мы используем комбинацию H2, аннотаций JPA, Spring и Hibernate для разработки нашего веб-приложения. Мы используем H2 в режиме совместимости с MODE=Oracle.

У нас есть класс ItSystem, который имеет связь «один ко многим» с классом ItSystemAka следующим образом:

@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 

Если у нас есть экземпляр ItSystem с несколькими экземплярами ItSystemAka, и мы пытаемся обновить экземпляр ItSystem в базе данных, то он теряет ссылку на все связанные экземпляры ItSystemAka. Глядя на базу данных с помощью консоли H2, я вижу, что для внешнего ключа (IT_SYSTEM_EDW_ID) для соответствующих строк в таблице ITSYSTEM_AKA устанавливается значение null.

Я пытался использовать диалект Oracle вместо родного диалекта H2, как указано на веб-сайте H2, но он дает те же результаты. Я также пытался использовать реальную базу данных Oracle вместо H2, и в этом случае все работает нормально.

Любая идея о том, что происходит не так?

Любая помощь приветствуется.

С уважением, Приеш


person Priyesh    schedule 26.09.2011    source источник


Ответы (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 всегда создает двунаправленное отношение

person Yappie    schedule 26.09.2011
comment
Это работает, однако мы надеялись использовать однонаправленную ассоциацию «один ко многим». Я также до сих пор не понимаю, почему обновление сущности с однонаправленной ассоциацией «один ко многим» работает с Oracle, но не с H2. С уважением, Приеш - person Priyesh; 27.09.2011
comment
Прежде всего, если вы пытаетесь составить карту @Column(name="ITSYSTEM_EDW_ID") private BigDecimal itSystemEdwId; , вы пытаетесь сделать свою ассоциацию двунаправленной. - person Yappie; 28.09.2011