Skip to content

Commit 6a7a1a6

Browse files
authored
BAEL-5763: Fix the HibernateException: Illegal attempt to associate a collection with two open sessions (#18698)
1 parent 62a81ba commit 6a7a1a6

File tree

4 files changed

+233
-0
lines changed

4 files changed

+233
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.baeldung.hibernate.hibernateexception;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
import jakarta.persistence.CascadeType;
7+
import jakarta.persistence.Entity;
8+
import jakarta.persistence.GeneratedValue;
9+
import jakarta.persistence.GenerationType;
10+
import jakarta.persistence.Id;
11+
import jakarta.persistence.OneToMany;
12+
13+
@Entity
14+
public class Author {
15+
16+
@Id
17+
@GeneratedValue(strategy = GenerationType.AUTO)
18+
private Long id;
19+
20+
private String name;
21+
22+
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
23+
private List<Book> books;
24+
25+
public Author(String name) {
26+
this.name = name;
27+
this.books = new ArrayList<>();
28+
}
29+
30+
Author() {
31+
}
32+
33+
public Long getId() {
34+
return id;
35+
}
36+
37+
public void setId(Long id) {
38+
this.id = id;
39+
}
40+
41+
public String getName() {
42+
return name;
43+
}
44+
45+
public void setName(String name) {
46+
this.name = name;
47+
}
48+
49+
public List<Book> getBooks() {
50+
return books;
51+
}
52+
53+
public void setBooks(List<Book> books) {
54+
this.books = books;
55+
}
56+
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.baeldung.hibernate.hibernateexception;
2+
3+
import jakarta.persistence.Entity;
4+
import jakarta.persistence.GeneratedValue;
5+
import jakarta.persistence.GenerationType;
6+
import jakarta.persistence.Id;
7+
import jakarta.persistence.ManyToOne;
8+
9+
@Entity
10+
public class Book {
11+
12+
@Id
13+
@GeneratedValue(strategy = GenerationType.AUTO)
14+
private Long id;
15+
16+
private String title;
17+
18+
@ManyToOne
19+
private Author author;
20+
21+
public Book(String title) {
22+
this.title = title;
23+
}
24+
25+
Book() {
26+
}
27+
28+
public Long getId() {
29+
return id;
30+
}
31+
32+
public void setId(Long id) {
33+
this.id = id;
34+
}
35+
36+
public String getTitle() {
37+
return title;
38+
}
39+
40+
public void setTitle(String title) {
41+
this.title = title;
42+
}
43+
44+
public Author getAuthor() {
45+
return author;
46+
}
47+
48+
public void setAuthor(Author author) {
49+
this.author = author;
50+
}
51+
52+
}
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,85 @@
1+
package com.baeldung.hibernate.hibernateexception;
2+
3+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
4+
5+
import org.hibernate.HibernateException;
6+
import org.hibernate.Session;
7+
import org.junit.jupiter.api.Test;
8+
9+
class HibernateExceptionUnitTest {
10+
11+
@Test
12+
void givenAnEntity_whenChangesUseTheSameHibernateSession_thenThoseChangesCanBeUpdated() {
13+
try (Session session1 = HibernateUtil.getSessionFactory()
14+
.openSession()) {
15+
session1.beginTransaction();
16+
17+
Author author = new Author("Jane Austen");
18+
session1.persist(author);
19+
20+
Book newBook = new Book("Pride and Prejudice");
21+
author.getBooks()
22+
.add(newBook);
23+
24+
session1.update(author);
25+
26+
session1.getTransaction()
27+
.commit();
28+
}
29+
}
30+
31+
@Test
32+
void givenAnEntity_whenChangesSpanMultipleHibernateSessions_thenThoseChangesCanBeMerged() {
33+
try (Session session1 = HibernateUtil.getSessionFactory()
34+
.openSession();
35+
Session session2 = HibernateUtil.getSessionFactory()
36+
.openSession()) {
37+
session1.beginTransaction();
38+
39+
Author author = new Author("Leo Tolstoy");
40+
session1.persist(author);
41+
session1.getTransaction()
42+
.commit();
43+
44+
session2.beginTransaction();
45+
46+
Book newBook = new Book("War and Peace");
47+
author.getBooks()
48+
.add(newBook);
49+
session2.merge(author);
50+
51+
session2.getTransaction()
52+
.commit();
53+
}
54+
}
55+
56+
@Test
57+
void givenAnEntity_whenChangesSpanMultipleHibernateSessions_thenThoseChangesCanNotBeUpdated() {
58+
assertThatThrownBy(() -> {
59+
try (Session session1 = HibernateUtil.getSessionFactory()
60+
.openSession();
61+
Session session2 = HibernateUtil.getSessionFactory()
62+
.openSession()) {
63+
session1.beginTransaction();
64+
65+
Author author = new Author("Leo Tolstoy");
66+
session1.persist(author);
67+
68+
session1.getTransaction()
69+
.commit();
70+
71+
session2.beginTransaction();
72+
73+
Book newBook = new Book("War and Peace");
74+
author.getBooks()
75+
.add(newBook);
76+
session2.update(author);
77+
78+
session2.getTransaction()
79+
.commit();
80+
}
81+
}).isInstanceOf(HibernateException.class)
82+
.hasMessageContaining("Illegal attempt to associate a collection with two open sessions");
83+
}
84+
85+
}

0 commit comments

Comments
 (0)