Hibernate @ManyToMany не заполняется таблица @JoinTable
Есть две таблицы children и section
Пытаюсь настроить отношение ManyToMany
таблицы children и section заполняются но таблица child_section которая является JoinTable всегда пустая.
При попытке получить children из Section через запрос Section section = session.get(Section.class,2);
Получаю только экземпляр Section без children
Возможно ошибка описана где то тут
Hibernate: insert into children (age, name) values (?, ?)
Hibernate: insert into children (age, name) values (?, ?)
Hibernate: insert into children (age, name) values (?, ?)
мая 01, 2022 7:28:30 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PoolState stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:postgresql://localhost:5432/my_db]
Exception in thread "main" java.lang.IllegalStateException: Transaction already active
at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:74)
at org.hibernate.internal.AbstractSharedSessionContract.beginTransaction(AbstractSharedSessionContract.java:468)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:351)
at jdk.proxy2/jdk.proxy2.$Proxy37.beginTransaction(Unknown Source)
at hibernate.many_to_many.Test.main(Test.java:35)
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "section")
public class Section {
@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "name")
private String name;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "child_section",
joinColumns = @JoinColumn(name = "section_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "child_id", referencedColumnName = "id"))
private List<Child> children;
public List<Child> getChildren() {
return children;
}
public void setChildren(List<Child> children) {
this.children = children;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Section() {
}
public Section(String name) {
this.name = name;
}
public void addChildrenToSection(Child child){
if (children == null){
children = new ArrayList<>();
}
children.add(child);
}
@Override
public String toString() {
return "Section{" +
"id=" + id +
", name='" + name + '\'' +
'}'+"\n";
}
}
import javax.persistence.*;
import javax.persistence.GenerationType;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "children")
public class Child {
@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "name")
private String firstName;
@Column(name = "age")
private int age;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "child_section",
joinColumns = @JoinColumn(name = "child_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "section_id", referencedColumnName = "id"))
private List<Section> sections;
public List<Section> getSections() {
return sections;
}
public void setSections(List<Section> sections) {
this.sections = sections;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Child() {
}
public Child(String firstName, int age) {
this.firstName = firstName;
this.age = age;
}
@Override
public String toString() {
return "Child{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", age=" + age +
'}';
}
public void addSectionToChildren(Section section){
if (sections ==null){
sections = new ArrayList<>();
}
sections.add(section);
}
}
Метод тестирования
import hibernate.many_to_many.entity.Child;
import hibernate.many_to_many.entity.Section;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test {
public static void main(String[] args) {
SessionFactory sessionFactory = new Configuration()
.configure("hibernate.cfg.xml")
.addAnnotatedClass(Child.class)
.addAnnotatedClass(Section.class)
.buildSessionFactory();
Session session = null;
try {
session = sessionFactory.getCurrentSession();
session.beginTransaction();
Section section = session.get(Section.class,2);
System.out.println(section);
System.out.println(section.getChildren());
session.beginTransaction().commit();
} finally {
session.close();
sessionFactory.close();
}
}
}
Ответы (1 шт):
По строчке в логах Exception in thread "main" java.lang.IllegalStateException: Transaction already active можно предположить, что где-то транзакция открывается 2 раза.
Попробуйте, когда начинаете транзакцию, сохранять ее значение в переменную, а потом уже коммитить, а не вызвывать beginTransaction() 2 раза.
Session session = sessionFactory.openSession();// или как вам удобно
Transaction tx = session.beginTransaction(); //<--
//smth actions
tx.commit(); //<--
session.close();
Вот пример