Skip to content

Commit fa2a729

Browse files
committed
BAEL-5763: Fix the HibernateException: Illegal attempt to associate a collection with two open sessions
1 parent 5daaf34 commit fa2a729

File tree

4 files changed

+226
-0
lines changed

4 files changed

+226
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.baeldung.hibernate.hibernateexception;
2+
3+
import java.util.List;
4+
5+
import jakarta.persistence.CascadeType;
6+
import jakarta.persistence.Entity;
7+
import jakarta.persistence.Id;
8+
import jakarta.persistence.OneToMany;
9+
10+
@Entity
11+
public class Author {
12+
13+
@Id
14+
private Long id;
15+
16+
private String name;
17+
18+
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
19+
private List<Book> books;
20+
21+
public Long getId() {
22+
return id;
23+
}
24+
25+
public void setId(Long id) {
26+
this.id = id;
27+
}
28+
29+
public String getName() {
30+
return name;
31+
}
32+
33+
public void setName(String name) {
34+
this.name = name;
35+
}
36+
37+
public List<Book> getBooks() {
38+
return books;
39+
}
40+
41+
public void setBooks(List<Book> books) {
42+
this.books = books;
43+
}
44+
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.baeldung.hibernate.hibernateexception;
2+
3+
import jakarta.persistence.Entity;
4+
import jakarta.persistence.Id;
5+
import jakarta.persistence.ManyToOne;
6+
7+
@Entity
8+
public class Book {
9+
10+
@Id
11+
private Long id;
12+
13+
private String title;
14+
15+
@ManyToOne
16+
private Author author;
17+
18+
public Long getId() {
19+
return id;
20+
}
21+
22+
public void setId(Long id) {
23+
this.id = id;
24+
}
25+
26+
public String getTitle() {
27+
return title;
28+
}
29+
30+
public void setTitle(String title) {
31+
this.title = title;
32+
}
33+
34+
public Author getAuthor() {
35+
return author;
36+
}
37+
38+
public void setAuthor(Author author) {
39+
this.author = author;
40+
}
41+
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.baeldung.hibernate.hibernateexception;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
import org.hibernate.SessionFactory;
7+
import org.hibernate.boot.Metadata;
8+
import org.hibernate.boot.MetadataSources;
9+
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
10+
import org.hibernate.service.ServiceRegistry;
11+
12+
public class HibernateUtil {
13+
private static SessionFactory sessionFactory;
14+
15+
public static SessionFactory getSessionFactory() {
16+
if (sessionFactory == null) {
17+
Map<String, Object> settings = new HashMap<>();
18+
settings.put("hibernate.connection.driver_class", "org.h2.Driver");
19+
settings.put("hibernate.connection.url", "jdbc:h2:mem:test");
20+
settings.put("hibernate.connection.username", "sa");
21+
settings.put("hibernate.connection.password", "");
22+
settings.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
23+
settings.put("hibernate.show_sql", "true");
24+
settings.put("hibernate.hbm2ddl.auto", "create-drop");
25+
26+
ServiceRegistry standardRegistry = new StandardServiceRegistryBuilder().applySettings(settings)
27+
.build();
28+
29+
Metadata metadata = new MetadataSources(standardRegistry).addAnnotatedClasses(Author.class, Book.class)
30+
.getMetadataBuilder()
31+
.build();
32+
33+
sessionFactory = metadata.getSessionFactoryBuilder()
34+
.build();
35+
}
36+
37+
return sessionFactory;
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package com.baeldung.hibernate.hibernateexception;
2+
3+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
4+
5+
import java.util.ArrayList;
6+
7+
import org.hibernate.HibernateException;
8+
import org.hibernate.Session;
9+
import org.junit.jupiter.api.Test;
10+
11+
class HibernateExceptionUnitTest {
12+
13+
@Test
14+
void whenUsingOneHibernateSession_thenCorrect() {
15+
try (Session session1 = HibernateUtil.getSessionFactory()
16+
.openSession()) {
17+
session1.beginTransaction();
18+
19+
Author author = new Author();
20+
author.setId(2L);
21+
author.setName("Jane Austen");
22+
author.setBooks(new ArrayList<Book>());
23+
session1.persist(author);
24+
25+
Author persistedAuthor = session1.get(Author.class, 2L);
26+
27+
Book newBook = new Book();
28+
newBook.setId(1L);
29+
newBook.setTitle("Pride and Prejudice");
30+
persistedAuthor.getBooks()
31+
.add(newBook);
32+
session1.update(persistedAuthor);
33+
34+
session1.getTransaction()
35+
.commit();
36+
}
37+
}
38+
39+
@Test
40+
void whenUsingMoreThanOneHibernateSessionWithMergeMethod_thenCorrect() {
41+
try (Session session1 = HibernateUtil.getSessionFactory()
42+
.openSession();
43+
Session session2 = HibernateUtil.getSessionFactory()
44+
.openSession()) {
45+
session1.beginTransaction();
46+
47+
Author author = new Author();
48+
author.setId(3L);
49+
author.setName("Leo Tolstoy");
50+
author.setBooks(new ArrayList<Book>());
51+
session1.persist(author);
52+
Author persistedAuthor = session1.get(Author.class, 3L);
53+
session1.getTransaction()
54+
.commit();
55+
56+
session2.beginTransaction();
57+
Book newBook = new Book();
58+
newBook.setId(1L);
59+
newBook.setTitle("War and Peace");
60+
persistedAuthor.getBooks()
61+
.add(newBook);
62+
session2.merge(persistedAuthor);
63+
session2.getTransaction()
64+
.commit();
65+
}
66+
}
67+
68+
@Test
69+
void whenUsingMoreThanOneHibernateSession_thenThrowHibernateException() {
70+
assertThatThrownBy(() -> {
71+
try (Session session1 = HibernateUtil.getSessionFactory()
72+
.openSession();
73+
Session session2 = HibernateUtil.getSessionFactory()
74+
.openSession()) {
75+
session1.beginTransaction();
76+
77+
Author author = new Author();
78+
author.setId(1L);
79+
author.setName("Leo Tolstoy");
80+
author.setBooks(new ArrayList<Book>());
81+
session1.persist(author);
82+
Author persistedAuthor = session1.get(Author.class, 1L);
83+
session1.getTransaction()
84+
.commit();
85+
86+
session2.beginTransaction();
87+
Book newBook = new Book();
88+
newBook.setId(1L);
89+
newBook.setTitle("War and Peace");
90+
persistedAuthor.getBooks()
91+
.add(newBook);
92+
session2.update(persistedAuthor);
93+
session2.getTransaction()
94+
.commit();
95+
}
96+
}).isInstanceOf(HibernateException.class)
97+
.hasMessageContaining("Illegal attempt to associate a collection with two open sessions");
98+
}
99+
100+
}

0 commit comments

Comments
 (0)