我有两个表'STUDENT'(pk -自动生成的学生标识)和'Address'。address_id是Address表的pk,它必须与学生标识具有相同的值。
实体:
@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)
}
}
我面临的问题是因为级联。所有JPA尝试保存子实体,即父实体Student之前的Address,但ADDRESS_ID具有NOT NULL约束,并且我遇到约束违规异常。如何一次性保存这两个实体。请帮助。提前感谢
1条答案
按热度按时间e5njpo681#
你问的
如何一次保存实体和关联实体。
让我们把“一次完成”翻译成一个事务,有很多方法可以实现这一点,所有这些方法都在于这样一个事实:对于持久化实体,在提交整个事务之前的适当时间点进行刷新。
解决方案
一种做法是根据JPA规范采用一种具有可延迟约束的后缓存机制,先持久化
Student
和Address
实体,通过刷新从数据库中获取生成器的id,然后在它们之间建立适当的绑定和关联,最后提交事务。为了演示它,从会话抽象开始,即EntityManager,它代表一级缓存,您可以通过EntityManagerFactory示例化它,它实际上代表二级缓存。
另外专门针对PK和FK列最常建立索引,因此共享PK可以将索引占用空间减少一半,这是可取的,因为您希望将所有索引存储到内存中以加快索引扫描,您可能会在此article中进行OneToOne关联优化。
注意事项
总是close所有手动示例化的entityManager。