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