Using PostgreSQL, why doesn't Hibernate/JPA create cascade constraints?
我有一个实体
1 2 | @OneToMany(cascade = CascadeType.ALL, mappedBy ="bar") private Set<Foo> fooSet; |
和实体
1 2 3 | @ManyToOne(optional = false) @JoinColumn(name ="bar_id") private Bar bar; |
Hibernate在foo.bar-> bar.id上创建外键约束,但未指定
或者,我可以在数据库中手动添加
谢谢。
更新-这是我的JPA / Hibernate / PostgreSQL配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy"> <constructor-arg> <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="org.postgresql.Driver" /> <property name="url" value="jdbc:postgresql://localhost:5432/my_db" /> <property name="username" value="my_username" /> <property name="password" value="my_password" /> </bean> </constructor-arg> </bean> <bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" /> <property name="showSql" value="true" /> <property name="generateDdl" value="true" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="jpaVendorAdapter" ref="jpaAdapter" /> <property name="jpaProperties"> <props> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> <property name="dataSource" ref="dataSource" /> </bean> |
更新2-阐明了我的意思:创建了外键约束,但是我想知道为什么它没有指定
Hibernate自己手动管理级联操作。而且,如果您要在数据库上进行级联,而不是在Hibernate中声明它们(出于性能问题),则在某些情况下可能会出错。这是因为Hibernate将实体存储在其会话缓存中,因此它不会知道数据库如何级联删除某些内容。
当您使用二级缓存时,情况甚至更糟,因为此缓存的生存期比会话长,并且只要会话中存储了较长的旧值,db-side的此类更改将对其他会话不可见。
我已经阅读了一些Hibernate资料(确实令人不愉快的经验),并且我怀疑在任何情况下都可以在数据库端管理级联-Hibernate设计做出的太多假设与数据库现实不兼容。<铅>
使用
1 | cascade = CascadeType.ALL |
如果执行任何操作,
会使hibernate状态遍历此关系。它不影响生成的DLL。
如果要删除fooSet中的所有实体,请添加orphanRemoval属性。
1 | @OneToMany(cascade = CascadeType.ALL, mappedBy ="bar", orphanRemoval=true) |
也使用
1 | <property name="generateDdl" value="true" /> |
仅适用于开发环境。不要将其用于生产。 (例如,如果您对一个属性/列进行重命名(例如,创建另一个列,甚至可能删除前一个列),则hibernate状态将无法更改表架构。)