java - 使用 PostgreSQL,为什么 Hibernate/JPA 不创建级联约束?

标签 java hibernate postgresql jpa foreign-keys

我有一个实体 Bar:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "bar")
private Set<Foo> fooSet;

还有一个实体Foo:

@ManyToOne(optional = false)
@JoinColumn(name = "bar_id")
private Bar bar;

Hibernate 在 foo.bar -> bar.id 上创建外键约束,但它没有指定 ON DELETE CASCADE。为什么不?有什么方法可以实现吗?

或者,我可以在数据库中手动添加 ON DELETE CASCADE(并禁用 DDL 生成),这是一个好的做法吗?而且,我是否必须修改我的代码以某种方式让 Hibernate 知道相关记录已被数据库自动删除?

谢谢。

更新 - 这是我的 JPA/Hibernate/PostgreSQL 配置:

<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 - 阐明了我的意思:创建了外键约束,但我想知道为什么它没有指定 ON DELETE CASCADE(相应地更改了原始问题)

最佳答案

Hibernate 手动管理级联操作。更重要的是,如果您要在数据库上进行级联,而不是在 Hibernate 中声明它们(出于性能问题),您在某些情况下可能会出错。这是因为 Hibernate 将实体存储在其 session 缓存中,因此它不知道数据库在级联中删除某些内容。

当你使用二级缓存时,你的情况会更糟,因为这个缓存的生命周期比 session 长,并且数据库端的此类更改将对其他 session 不可见,因为在这个缓存中存储了很长时间的旧值。

我已经阅读了一些 Hibernate 资源(非常不愉快的经历),我怀疑在任何情况下都可以在数据库端管理级联 - Hibernate 设计做出了太多与数据库现实不兼容的假设。

关于java - 使用 PostgreSQL,为什么 Hibernate/JPA 不创建级联约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9887242/

相关文章:

java - Hibernate flush_before_completion 像 post flush 或 pre flush 一样工作吗?

sql - 计算列上的窗口函数

java - 作为对象容器的 Singleton 类型的类

java - 连接错误 : TypeError ('ref() does not take keyword arguments' , )})

java - 我需要 JavaScript 来进行打印吗

java - 设置 ant bootclasspath : JDK 1. 7 有一个新的 javac 警告,用于设置没有 bootclasspath 的旧源

java - 使用 hibernate 从数据库中删除项目

java - Hibernate/JPA 查询连接子类的可嵌入属性

postgresql - 使用postgresql的ORDER BY、OFFSET和LIMIT优化SELECT查询

postgresql - 你能在 Postgres 中已经存在的列上创建一个序列吗