繁体   English   中英

Sprint Data JPA - 使用共享主键保存父实体的子实体

[英]Sprint Data JPA - save child entity with parent with shared primary key

我有两个表'STUDENT'(pk - student_id autogenerated) 和'Address'。 address_id 是 Address 表的 pk,它必须与 student_id 的值相同。

实体:

@Entity
@Table(name = "student")
Public class Student{

    @Id
    @GeneratedValue
    @Column(name = "STUDENT_ID",updatable = false,insertable = false)
    private long Id;


    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="STUDENT_ID")
    private Address address;

.....
//getters setters
}


@Entity
@Table(name = "address")
Public class Address{

    @Id
    @Column(name = "ADDRSS_ID",updatable = false,insertable = false)
    private long Id;


    @OneToOne
    private Student student;

.....
//getters setters
}



service 

public class Service {

 @Autowired StudentRepository repo;

 public void saveStudent(Student s){

 repo.save(s)
}

}

我面临的问题是因为 cascade.ALL JPA 试图在父实体 Student 之前保存子实体,即 Address,但是 ADDRESS_ID 没有 NULL 约束,我收到约束违规异常。 如何同时保存两者。 请帮忙。 提前致谢

您询问

如何同时保存(实体和关联实体)。

让我们将“一次性”翻译为一次事务,实现它的方法有很多种,所有这些都在于这样一个事实,即在提交整个事务之前在适当的时间点完成持久化实体刷新。

解决方案

一种做法是采用基于 JPA 规范并具有可延迟约束的后台缓存机制。 首先持久化StudentAddress实体,以通过刷新从数据库中的生成器获取 id,然后在它们之间创建适当的绑定和关联,最后提交事务。

为了演示它,从会话抽象开始,即作为一级缓存的EntityManager ,您可以通过EntityManagerFactory实例化它,它确实代表二级缓存。

EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
entityManager.persist(Not_associated_entities);
...
flush();
...
entityManager.merge(associated_entities);
...
entityManager.getTransaction().commit();
entityManager.close();

另外专门针对PK和FK列最常被索引,所以共享PK可以减少一半的索引占用空间,这是可取的,因为你想把你所有的索引都存储到内存中以加快索引扫描,你可以在OneToOne关联优化中这篇文章

警告

始终关闭entityManager 的所有手动实例化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM