我在类A和类B之间有@ManyToMany关系:类A引用类B实例的集合,并且此关系配置为CascadeType.ALL。因此,当A与实体管理器一起持久化时,A引用的B实例也会被持久化。
A和B都有一个使用GenerationType.IDENTITY策略声明的ID,以使用MySQL数据库中的auto_inc。
问题是:
=> JPA尝试保留B对象,尽管它们已经被持久化(它们刚被加载)。
我不明白为什么它会再次尝试保留它们,它们已经正确加载,并且它们的自动生成的id也已经很好地加载了。
ManyToMany声明:
@ManyToMany(cascade={CascadeType.ALL})
@JoinTable(name = "ENTRY_ENTITIES", joinColumns =
@JoinColumn(name = "ENTRY", referencedColumnName = "ID"),
inverseJoinColumns = @JoinColumn(name = "ENTITY", referencedColumnName = "ID"))
private List<Entity> entities;
从数据库加载现有对象的查询:
T result = (T) entityManager.createQuery("SELECT x FROM " + entityName + " x WHERE x.externalId='" + externalId + "'").getSingleResult();
坚持:
UserTransaction transaction = getTransaction();
try {
transaction.begin();
entityManager.persist(entity);
transaction.commit();
} catch (Throwable t) {
Logger.getLogger(JpaDao.class.getName()).log(Level.SEVERE, null, t);
}
非常感谢你的帮助!
答案 0 :(得分:2)
我不完全确定这是您问题的原因,但您应该将整个内容包含在事务中。不只是持久性部分:
start transaction
load B from DB
create new A
add B to A
commit transaction
正如我在评论中所说,您还有其他设计和编码问题:
SELECT x FROM A x WHERE x.externalId = :externalId
答案 1 :(得分:1)
这些B实体可能是您将其添加到A的时间点的另一个持久性上下文的一部分。您是否尝试在启动事务后在B实体上使用merge operation,之前< / strong>将它们添加到您的A实体。