Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java &引用;已分离实体传递到持久化错误“;使用JPA/EJB代码_Java_Jpa_Ejb 3.0 - Fatal编程技术网

Java &引用;已分离实体传递到持久化错误“;使用JPA/EJB代码

Java &引用;已分离实体传递到持久化错误“;使用JPA/EJB代码,java,jpa,ejb-3.0,Java,Jpa,Ejb 3.0,我正在尝试运行以下基本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.ej

我正在尝试运行以下基本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分配修复了它


但是我没有得到它,我需要修改什么才能让代码正常工作?

我得到了答案,我使用了:

em.persist(user);
我使用“合并”代替“持久化”:

em.merge(user);

但不知道,为什么坚持不起作用(

发生错误是因为设置了对象的ID。Hibernate区分暂时对象和分离对象,并且
persist
仅适用于暂时对象。如果
persist
得出对象已分离的结论(由于ID已设置),它将返回“传递给persist的分离对象”错误。您可以找到更多详细信息和

但是,这仅适用于指定要自动生成的主键的情况:如果将字段配置为始终手动设置,则代码有效。

假设您有两个实体
相册
照片
。相册包含许多照片,因此是一对多关系

专辑类

@Entity
public class Album {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    Integer albumId;

    String albumName;

    @OneToMany(targetEntity=Photo.class,mappedBy="album",cascade={CascadeType.ALL},orphanRemoval=true)
    Set<Photo> photos = new HashSet<Photo>();
}
@Entity
public class Photo{
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    Integer photo_id;

    String photoName;

    @ManyToOne(targetEntity=Album.class)
    @JoinColumn(name="album_id")
    Album album;

}
在持久化或合并之前,您要做的是在每张照片中设置相册引用

        Album myAlbum = new Album();
        Photo photo1 = new Photo();
        Photo photo2 = new Photo();

        photo1.setAlbum(myAlbum);
        photo2.setAlbum(myAlbum);       

这就是在持久化或合并之前附加相关实体的方法。

我遇到了这个问题,它是由二级缓存引起的:

  • 我使用hibernate保存了一个实体
  • 然后,我删除了从一个单独的进程创建的行,该进程不与二级缓存交互
  • 我保留了另一个具有相同标识符的实体(我的标识符值不是自动生成的)
  • 因此,由于缓存没有失效,hibernate假定它正在处理同一实体的分离实例。

    remove

    user.setId(1);
    
    因为它是在数据库上自动生成的,
    然后继续使用persist命令。

    我知道这有点太晚了,而且每个人都得到了答案。但还有一点需要补充:当设置GenerateType时,对象上的persist()需要生成一个id

    如果用户已经为Id设置了一个值,hibernate将其视为已保存的记录,因此将其视为已分离

    如果id为null-在这种情况下,当类型为AUTO或IDENTITY等时会引发null指针异常,除非id是从表或序列等生成的

    设计:当表有一个bean属性作为主键时,就会发生这种情况。 仅当自动生成id时,才能设置GenerateType。 删除此项,插入项应使用用户指定的id。
    (将属性映射到主键字段是一种糟糕的设计)

    此处.persist()只会插入记录。如果使用.merge()它将检查是否存在具有当前ID的记录,如果存在,它将更新,否则它将插入新记录。

    如果您在实体中使用生成
    ID=GenerationType.AUTO
    策略


    user.setId(1)
    替换为
    user.setId(null)
    ,问题就解决了。

    如果将数据库中的id设置为主键并自动递增,则此行代码错误:

    user.setId(1);
    
    试试这个:

    public static void main(String[] args){
             UserBean user = new UserBean();
             user.setUserName("name1");
             user.setPassword("passwd1");
             em.persist(user);
      }
    

    当我说,我使用的是JPA而不是Hibernate时,我在技术上是正确的吗?所以,上面的陈述不应该适用于正确的吗?我是JPA的新手(准确地说是3天:P)Sun的JPA Javadoc()和Toplink的JPA Javadoc()完全相同,表明你在技术上是正确的。然而,它实际上归结为规范所说的persist()很遗憾,我不知道这是什么。这个解决方案对我有效。我一直在保存一个对象,将ID存储在某个地方。然后我想用一个新值覆盖现有的对象,所以我创建了该对象,将ID复制回来,当我试图保存时,它爆炸了。最后,我不得不重新查询数据库(findById),进行更改,然后保留该对象。这不是解决方案!我知道,但这对我有效。这里还有其他对您有效的答案吗?如果是,我将非常乐意选择它。它有效是因为您的对象已从hibernate会话中分离,或者对象是暂时的,但hibernate认为它已分离,因为您声明的主键,使用merge将对象再次附加到会话,这使您能够更新数据库中的对象;请参阅:如果使用泛型,则无需使用“targetEntity=Photo.class”您好,在将相册对象设置为photo1和photo2之后…我们必须保存照片或相册列表的对象是什么?我尝试了,我知道出现了此错误:
    分离实体传递到persist
    在得到您的答案之前,我花费了大量时间。非常感谢!