JPA / EJB 코드와 함께 "오류를 지속하기 위해 전달 된 분리 된 엔티티"
이 기본 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 할당을 제거하면 문제가 해결되었습니다.
하지만 이해하지 못했습니다. 코드가 작동하려면 무엇을 수정해야합니까?
두 개의 엔티티 Album
와 Photo
. 앨범에는 많은 사진이 포함되어 있으므로 일대 다 관계입니다.
앨범 클래스
@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);
이것이 지속 또는 병합하기 전에 관련 엔터티를 연결하는 방법입니다.
The error occurs because the object's ID is set. Hibernate distinguishes between transient and detached objects and persist
works only with transient objects. If persist
concludes the object is detached (which it will because the ID is set), it will return the "detached object passed to persist" error. You can find more details here and here.
However, this only applies if you have specified the primary key to be auto-generated: if the field is configured to always be set manually, then your code works.
remove
user.setId(1);
because it is auto generate on the DB, and continue with persist command.
I got the answer, I was using:
em.persist(user);
I used merge in place of persist:
em.merge(user);
But no idea, why persist didn't work. :(
if you use to generate the id = GenerationType.AUTO
strategy in your entity.
Replaces user.setId (1)
by user.setId (null)
, and the problem is solved.
I know its kind of too late and proly every one got the answer. But little bit more to add to this: when GenerateType is set, persist() on an object is expected to get an id generated.
If there is a value set to the Id by user already, hibernate treats it as saved record and so it is treated as detached.
if the id is null - in this situation a null pointer exception is raised when the type is AUTO or IDENTITY etc unless the id is generated from a table or a sequece etc.
design: this happens when the table has a bean property as primary key. GenerateType must be set only when an id is autogenerated. remove this and the insert should work with the user specified id. (it is a bad design to have a property mapped to primary key field)
Here .persist() only will insert the record.If we use .merge() it will check is there any record exist with the current ID, If it exists, it will update otherwise it will insert a new record.
If you set id in your database to be primary key and autoincrement, then this line of code is wrong:
user.setId(1);
Try with this:
public static void main(String[] args){
UserBean user = new UserBean();
user.setUserName("name1");
user.setPassword("passwd1");
em.persist(user);
}
I had this problem and it was caused by the second level cache:
- I persisted an entity using hibernate
- Then I deleted the row created from a separate process that didn't interact with the second level cache
- 동일한 식별자로 다른 엔터티를 유지했습니다 (내 식별자 값이 자동 생성되지 않음).
따라서 캐시가 무효화되지 않았기 때문에 Hibernate는 동일한 엔티티의 분리 된 인스턴스를 처리한다고 가정했습니다.
'developer tip' 카테고리의 다른 글
버튼의 PNG 색상 변경-iOS (0) | 2020.10.11 |
---|---|
jQuery를 사용하여 마우스 오버시 툴팁 메시지를 어떻게 표시 할 수 있습니까? (0) | 2020.10.11 |
245px에서 "px"를 삭제하는 방법 (0) | 2020.10.11 |
mvc4 razor의 텍스트 상자에 숫자 만 허용하는 방법 (0) | 2020.10.11 |
ViewModel에서 창 닫기 (0) | 2020.10.11 |