我正在尝试运行这个基本的JPA / EJB代码:
public static void main(String[] args){
UserBean user = new UserBean();
user.setId(1);
user.setUserName("name1");
user.setPassword("passwd1");
em.persist(user);
}
我收到此错误:
javax.ejb.EJBException: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.JPA.Database
有任何想法吗?
我在互联网上搜索,我找到的原因是:
这是由您创建对象的方式引起的,即如果您明确设置了ID属性 . 删除ID分配修复了它 .
但我没有得到它,我需要修改什么来使代码工作?
10 回答
假设你有两个实体
Album
和Photo
. 相册包含许多照片,因此它是一对多的关系 .Album class
Photo class
在保留或合并之前您需要做的是在每张照片中设置“影集”参考 .
这是在持久化或合并之前附加相关实体的方法 .
发生错误是因为设置了对象的ID . Hibernate区分瞬态和分离对象,
persist
仅适用于瞬态对象 . 如果persist
结束对象已分离(因为ID已设置),则会返回"detached object passed to persist"错误 . 您可以找到更多详细信息here和here .但是,这仅适用于您已指定要自动生成的主键的情况:如果该字段配置为始终手动设置,则代码可以正常工作 .
去掉
因为它是在DB上自动生成的,并继续使用persist命令 .
我得到了答案,我正在使用:
我使用merge代替persist:
但不知道,为什么坚持不起作用 . :(
如果您用于在实体中生成
id = GenerationType.AUTO
策略 .用
user.setId (null)
替换user.setId (1)
,问题解决了 .我知道它太迟了,而且每个人都得到答案 . 但要添加一点:当GenerateType设置时,对象上的persist()应该生成一个id .
如果用户已将值设置为Id,则hibernate会将其视为已保存的记录,因此将其视为已分离 .
如果id为null - 在这种情况下,当类型为AUTO或IDENTITY等时引发空指针异常,除非id是从表或sequece等生成的 .
设计:当表具有bean属性作为主键时,会发生这种情况 . 只有在自动生成id时才必须设置GenerateType . 删除它,插入应该与用户指定的ID一起使用 . (将属性映射到主键字段是一种糟糕的设计)
这里 .persist() 只会插入记录 . 如果我们使用 .merge() 它将检查当前ID是否存在任何记录,如果存在,它将更新否则将插入新记录 .
我有这个问题,它是由二级缓存引起的:
我使用hibernate持久化了一个实体
然后我删除了从不与二级缓存交互的单独进程创建的行
我持有另一个具有相同标识符的实体(我的标识符值不是自动生成的)
因此,因为缓存没有失效,所以hibernate假定它正在处理同一实体的分离实例 .
如果您将数据库中的id设置为主键和自动增量,那么这行代码是错误的:
试试这个:
实体对象未实现
Serializable
接口的错误的另一个原因