BAEL-5439: PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate (#12303)
* BAEL-5439: added code samples for article * BAEL-5439: added static import for assertj
This commit is contained in:
parent
e798355a92
commit
ff3cc7b948
|
@ -0,0 +1,46 @@
|
||||||
|
package com.baeldung.hibernate.exception.detachedentity;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.exception.detachedentity.entity.Comment;
|
||||||
|
import com.baeldung.hibernate.exception.detachedentity.entity.Post;
|
||||||
|
|
||||||
|
public class HibernateUtil {
|
||||||
|
private static SessionFactory sessionFactory;
|
||||||
|
|
||||||
|
public static SessionFactory getSessionFactory() {
|
||||||
|
if (sessionFactory == null) {
|
||||||
|
try {
|
||||||
|
Configuration configuration = new Configuration();
|
||||||
|
Properties settings = new Properties();
|
||||||
|
settings.put(Environment.DRIVER, "org.hsqldb.jdbcDriver");
|
||||||
|
settings.put(Environment.URL, "jdbc:hsqldb:mem:transient");
|
||||||
|
settings.put(Environment.USER, "sa");
|
||||||
|
settings.put(Environment.PASS, "");
|
||||||
|
settings.put(Environment.DIALECT, "org.hibernate.dialect.HSQLDialect");
|
||||||
|
settings.put(Environment.SHOW_SQL, "true");
|
||||||
|
settings.put(Environment.FORMAT_SQL, "true");
|
||||||
|
settings.put(Environment.USE_SQL_COMMENTS, "true");
|
||||||
|
settings.put(Environment.HBM2DDL_AUTO, "update");
|
||||||
|
configuration.setProperties(settings);
|
||||||
|
|
||||||
|
configuration.addAnnotatedClass(Comment.class);
|
||||||
|
configuration.addAnnotatedClass(Post.class);
|
||||||
|
|
||||||
|
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties())
|
||||||
|
.build();
|
||||||
|
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sessionFactory;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.baeldung.hibernate.exception.detachedentity.entity;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Comment {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
public Comment(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Comment() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private Post post;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Post getPost() {
|
||||||
|
return post;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPost(Post post) {
|
||||||
|
this.post = post;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Comment{" + "id=" + id + ", name='" + text + '\'' + ", post=" + post + '}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.baeldung.hibernate.exception.detachedentity.entity;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Post {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
public Post() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Post(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Post{" + "id=" + id + ", text='" + title + '\'' + '}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
package com.baeldung.hibernate.exception.detachedentity;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.exception.detachedentity.entity.Comment;
|
||||||
|
import com.baeldung.hibernate.exception.detachedentity.entity.Post;
|
||||||
|
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import javax.persistence.PersistenceException;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
|
public class DetachedEntityUnitTest {
|
||||||
|
|
||||||
|
private static Session session;
|
||||||
|
private Post detachedPost;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void beforeEach() {
|
||||||
|
session = HibernateUtil.getSessionFactory()
|
||||||
|
.openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
this.detachedPost = new Post("Hibernate Tutorial");
|
||||||
|
session.persist(detachedPost);
|
||||||
|
session.evict(detachedPost);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void afterEach() {
|
||||||
|
clearDatabase();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDetachedPost_whenTryingToPersist_thenThrowException() {
|
||||||
|
detachedPost.setTitle("Hibernate Tutorial for Absolute Beginners");
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> session.persist(detachedPost))
|
||||||
|
.isInstanceOf(PersistenceException.class)
|
||||||
|
.hasMessageContaining("org.hibernate.PersistentObjectException: detached entity passed to persist");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDetachedPost_whenTryingToMerge_thenNoExceptionIsThrown() {
|
||||||
|
detachedPost.setTitle("Hibernate Tutorial for Beginners");
|
||||||
|
|
||||||
|
session.merge(detachedPost);
|
||||||
|
session.getTransaction()
|
||||||
|
.commit();
|
||||||
|
|
||||||
|
List<Post> posts = session.createQuery("Select p from Post p", Post.class)
|
||||||
|
.list();
|
||||||
|
assertThat(posts).hasSize(1);
|
||||||
|
assertThat(posts.get(0)
|
||||||
|
.getTitle()).isEqualTo("Hibernate Tutorial for Beginners");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDetachedPost_whenPersistingNewCommentWithIt_thenThrowException() {
|
||||||
|
Comment comment = new Comment("nice article!");
|
||||||
|
comment.setPost(detachedPost);
|
||||||
|
|
||||||
|
session.persist(comment);
|
||||||
|
session.getTransaction()
|
||||||
|
.commit();
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> session.persist(detachedPost))
|
||||||
|
.isInstanceOf(PersistenceException.class)
|
||||||
|
.hasMessageContaining("org.hibernate.PersistentObjectException: detached entity passed to persist");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDetachedPost_whenMergeAndPersistComment_thenNoExceptionIsThrown() {
|
||||||
|
Comment comment = new Comment("nice article!");
|
||||||
|
Post mergedPost = (Post) session.merge(detachedPost);
|
||||||
|
comment.setPost(mergedPost);
|
||||||
|
|
||||||
|
session.persist(comment);
|
||||||
|
session.getTransaction()
|
||||||
|
.commit();
|
||||||
|
|
||||||
|
List<Comment> comments = session.createQuery("Select c from Comment c", Comment.class)
|
||||||
|
.list();
|
||||||
|
Comment savedComment = comments.get(0);
|
||||||
|
assertThat(savedComment.getText()).isEqualTo("nice article!");
|
||||||
|
assertThat(savedComment.getPost()
|
||||||
|
.getTitle()).isEqualTo("Hibernate Tutorial");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearDatabase() {
|
||||||
|
if (!session.getTransaction()
|
||||||
|
.isActive()) {
|
||||||
|
session.beginTransaction();
|
||||||
|
}
|
||||||
|
session.createQuery("DELETE FROM Comment")
|
||||||
|
.executeUpdate();
|
||||||
|
session.createQuery("DELETE FROM Post")
|
||||||
|
.executeUpdate();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue