我在数据库中保存实体时遇到问题。
我喜欢(非常简化):
@Entity
public class Building {
@OneToMany(mappedBy = "building", fetch = FetchType.EAGER)
private List<Employee> employees;
}
@Entity
public class Employee {
@NotNull
@ManyToOne
@JoinFetch(INNER)
@JoinColumn
private Building building;
@PostLoad
private void onLoad(){
if (this.plannedOrder == null) {
//For old entities in this DB, update plannedOrder if null
if (this.order < FIRST.getCode()) {
this.plannedOrder = FIRST;
} else if (this.order >= FIRST.getCode() && this.order < SECOND.getCode()) {
this.plannedOrder = SECOND;
} else if (this.order >= DEFAULT.getCode() && this.order < SEC_LAST.getCode()) {
this.plannedOrder = DEFAULT;
} else if (this.order >= SEC_LAST.getCode() && this.order < LAST.getCode()) {
this.plannedOrder = SEC_LAST;
} else if (this.order >= LAST.getCode()) {
this.plannedOrder = LAST;
} else {
this.plannedOrder = DEFAULT;
}
}
}
问题是当我保存一个Employee实体时。在Building实体中,您将修改所有员工,因为@PostLoad注释,因此JPA将尝试更新这些实体。但是,我只想更新Employee实体。
有没有办法在不改变模型中的关系的情况下这样做?可以成为删除onLoad函数的解决方案吗?
谢谢!
编辑:
添加了PostLoad的PostLoad代码。这是对DB中的旧实体执行的修复,没有在保存时更新此字段。
已编辑2
这就是我用我的EntityManager保存我的实体Employee的方式(如果是新的Object,则保留,否则更新它)
if (entity.getId() == null) {
entityManager.persist(entity);
return entity;
}
return entityManager.merge(entity);
答案 0 :(得分:1)
只是扩展了Tobb的回答: 发生这种情况是因为您正在使用合并调用加载Employee。此实体与构建的关系为1:1,默认为Eagerly fetched,强制构建也被加载。
构建那么员工也有1:M,并且你用fetch = FetchType.EAGER标记了它,强制所有员工也被加载。
如果您不希望加载所有员工,从而强制JPA调用其postLoad方法,则需要阻止加载这些关系中的一个或多个。选项:
如果您选择使用延迟提取,则仍可以根据需要通过提取连接,查询提示和/或提取/加载组按查询覆盖此方法。
答案 1 :(得分:0)
加载Employee
- 实体时,您可能还会加载Building
- 实体(取决于您的JPA提供程序和版本,无论是fetchtype EAGER还是LAZY是默认值),以及加载时Building
- 实体,您还将加载与其相关联的所有Employees
。
这意味着加载一个Employee
- 实体将/可能加载连接到同一Employee
的所有Building
,从而为所有这些运行@PostLoad
- 方法。当在事务中发生这种情况时,我会假设在事务提交时,@PostLoad
- 方法所做的更改会保留。