Java JPA持久化来自多个关系的已持久化对象
我在类a和类B之间有一个@ManyToMany关系:类a引用了类B实例的集合,这个关系被配置为CascadeType.ALL。因此,当使用实体管理器持久化a时,a引用的B实例也会持久化 A和B都使用GenerationType.IDENTITY策略声明了一个ID,以使用MySQL数据库中的auto_inc 问题是:Java JPA持久化来自多个关系的已持久化对象,java,jpa,jpql,Java,Jpa,Jpql,我在类a和类B之间有一个@ManyToMany关系:类a引用了类B实例的集合,这个关系被配置为CascadeType.ALL。因此,当使用实体管理器持久化a时,a引用的B实例也会持久化 A和B都使用GenerationType.IDENTITY策略声明了一个ID,以使用MySQL数据库中的auto_inc 问题是: 我创建了一个新的 我使用JPQL从entityManager加载一些现有的B对象 我将B对象添加到A的B集合中 =>JPA尝试持久化B对象,尽管它们已经被持久化(它们刚刚被加载) 我
@ManyToMany(cascade={CascadeType.ALL})
@JoinTable(name = "ENTRY_ENTITIES", joinColumns =
@JoinColumn(name = "ENTRY", referencedColumnName = "ID"),
inverseJoinColumns = @JoinColumn(name = "ENTITY", referencedColumnName = "ID"))
private List<Entity> entities;
坚持:
UserTransaction transaction = getTransaction();
try {
transaction.begin();
entityManager.persist(entity);
transaction.commit();
} catch (Throwable t) {
Logger.getLogger(JpaDao.class.getName()).log(Level.SEVERE, null, t);
}
非常感谢你的帮助 我不能绝对肯定这是您的问题的原因,但您应该将整个事情包含在事务中。不仅仅是持久性部分:
start transaction
load B from DB
create new A
add B to A
commit transaction
正如我在评论中所说,您还有其他设计和编码问题:
- CascadeType.ALL在多个XXX关联上都是错误的。您不希望在删除A时删除A的所有B,因为这些B被其他As引用。这将导致违反约束(在最佳情况下)或数据库不一致(在最坏情况下,如果未定义约束)
- 不要在查询中使用字符串连接。使用参数化查询。这将避免引用问题和注入攻击:
从x中选择x,其中x.externalId=:externalId
start transaction
load B from DB
create new A
add B to A
commit transaction
正如我在评论中所说,您还有其他设计和编码问题:
- CascadeType.ALL在多个XXX关联上都是错误的。您不希望在删除A时删除A的所有B,因为这些B被其他As引用。这将导致违反约束(在最佳情况下)或数据库不一致(在最坏情况下,如果未定义约束)
- 不要在查询中使用字符串连接。使用参数化查询。这将避免引用问题和注入攻击:
从x中选择x,其中x.externalId=:externalId