Reputation:
guys I have this entity :
import lombok.*;
import javax.persistence.*;
import java.util.List;
@Entity
@Table(name = "clients")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Client {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "username")
private String username;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "dob")
private String dob;
@Column(name = "email")
private String email;
@Column(name = "password")
private String password;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "role_id")
private Role role;
@OneToMany(mappedBy = "client", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Card> cards;
@OneToMany(mappedBy = "client", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Address> addresses;
@OneToMany(mappedBy = "client", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Order> orders;
}
import lombok.*;
import javax.persistence.*;
import java.util.List;
@Entity
@Table(name = "roles")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "role", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Client> clients;
}
import lombok.*;
import ru.mialyshev.demo.demo.model.enums.*;
import javax.persistence.*;
import java.util.List;
@Entity
@Table(name = "orders")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "client_id")
private Client client;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "address_id")
private Address address;
@Enumerated(EnumType.STRING)
@Column(name = "delivery_type")
private Delivery delivery;
@Enumerated(EnumType.STRING)
@Column(name = "order_status")
private OrderStatus orderStatus;
@Enumerated(EnumType.STRING)
@Column(name = "payment_status")
private PaymentStatus paymentStatus;
@Enumerated(EnumType.STRING)
@Column(name = "payment_type")
private PaymentType paymentType;
@OneToMany(mappedBy = "order", fetch = FetchType.EAGER)
private List<OrderProduct> orderProducts;
}
import lombok.*;
import javax.persistence.*;
import java.util.List;
@Entity
@Table(name = "cards")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Card {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "card_number")
private String number;
@Column(name = "validaty_date")
private String validatyDate;
@Column(name = "card_owner")
private String owner;
@Column(name = "code")
private String code;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "client_id")
private Client client;
}
import lombok.*;
import javax.persistence.*;
import java.util.List;
@Entity
@Table(name = "addresses")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "country")
private String country;
@Column(name = "city")
private String city;
@Column(name = "postal_code")
private String postalCode;
@Column(name = "street")
private String street;
@Column(name = "house_number")
private String houseNumber;
@Column(name = "apartament_number")
private String apartamentNumber;
@Column(name = "is_saved")
private boolean isSaved;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "client_id")
private Client client;
@OneToMany(mappedBy = "address", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Order> orders;
}
And some service for him, which added new database entries. When I'm start this app (Spring boot + Spring Data), i am getting the following exception :
Failed to initialize JPA EntityManagerFactory: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags: [ru.mialyshev.demo.demo.model.Client.cards, ru.mialyshev.demo.demo.model.Client.orders]
2020-12-28 16:15:09.040 WARN 12012 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags: [ru.mialyshev.demo.demo.model.Client.cards, ru.mialyshev.demo.demo.model.Client.orders]
Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags: [ru.mialyshev.demo.demo.model.Client.cards, ru.mialyshev.demo.demo.model.Client.orders]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1788) ~[spring-beans-5.3.2.jar:5.3.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:609) ~[spring-beans-5.3.2.jar:5.3.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:531) ~[spring-beans-5.3.2.jar:5.3.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.2.jar:5.3.2]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.2.jar:5.3.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.2.jar:5.3.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.2.jar:5.3.2]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1159) ~[spring-context-5.3.2.jar:5.3.2]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913) ~[spring-context-5.3.2.jar:5.3.2]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:588) ~[spring-context-5.3.2.jar:5.3.2]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.1.jar:2.4.1]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767) ~[spring-boot-2.4.1.jar:2.4.1]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) ~[spring-boot-2.4.1.jar:2.4.1]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) ~[spring-boot-2.4.1.jar:2.4.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) ~[spring-boot-2.4.1.jar:2.4.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) ~[spring-boot-2.4.1.jar:2.4.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298) ~[spring-boot-2.4.1.jar:2.4.1]
at ru.mialyshev.demo.demo.DemoApplication.main(DemoApplication.java:10) ~[classes/:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags: [ru.mialyshev.demo.demo.model.Client.cards, ru.mialyshev.demo.demo.model.Client.orders]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421) ~[spring-orm-5.3.2.jar:5.3.2]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-5.3.2.jar:5.3.2]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.3.2.jar:5.3.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1847) ~[spring-beans-5.3.2.jar:5.3.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1784) ~[spring-beans-5.3.2.jar:5.3.2]
... 17 common frames omitted
Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags: [ru.mialyshev.demo.demo.model.Client.cards, ru.mialyshev.demo.demo.model.Client.orders]
at org.hibernate.loader.plan.exec.internal.AbstractLoadQueryDetails.generate(AbstractLoadQueryDetails.java:193) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails.<init>(EntityLoadQueryDetails.java:85) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.loader.plan.exec.internal.BatchingLoadQueryDetailsFactory.makeEntityLoadQueryDetails(BatchingLoadQueryDetailsFactory.java:64) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.<init>(AbstractLoadPlanBasedEntityLoader.java:97) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.<init>(AbstractLoadPlanBasedEntityLoader.java:112) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.loader.entity.plan.EntityLoader.<init>(EntityLoader.java:117) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.loader.entity.plan.EntityLoader.<init>(EntityLoader.java:30) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.loader.entity.plan.EntityLoader$Builder.byUniqueKey(EntityLoader.java:82) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.loader.entity.plan.EntityLoader$Builder.byPrimaryKey(EntityLoader.java:75) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.loader.entity.plan.AbstractBatchingEntityLoaderBuilder.buildNonBatchingLoader(AbstractBatchingEntityLoaderBuilder.java:30) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.loader.entity.BatchingEntityLoaderBuilder.buildLoader(BatchingEntityLoaderBuilder.java:61) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.createEntityLoader(AbstractEntityPersister.java:2610) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.createEntityLoader(AbstractEntityPersister.java:2632) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.generateDelayedEntityLoader(AbstractEntityPersister.java:4384) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.internal.util.collections.LazyIndexedMap.lockedComputeIfAbsent(LazyIndexedMap.java:77) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.internal.util.collections.LazyIndexedMap.computeIfAbsent(LazyIndexedMap.java:63) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.persister.entity.EntityLoaderLazyCollection.getOrBuildByLockMode(EntityLoaderLazyCollection.java:34) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.getLoaderByLockMode(AbstractEntityPersister.java:4375) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.createLoaders(AbstractEntityPersister.java:4362) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.postInstantiate(AbstractEntityPersister.java:4337) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.metamodel.internal.MetamodelImpl.initialize(MetamodelImpl.java:257) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:301) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:469) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.3.2.jar:5.3.2]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.3.2.jar:5.3.2]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-5.3.2.jar:5.3.2]
... 21 common frames omitted
Process finished with exit code 1
What am I doing wrong? Before that, I wrote an application with similar functionality and everything worked fine. Now, in the new application, these are the errors.
Upvotes: 1
Views: 6085
Reputation: 471
You have defined fetch = FetchType.EAGER
at your @OneToMany
relations. That means Hibernate would try to fetch them together with the related entities using a JOIN, with multiple relations in place, that would be way to huge. Generally it's not advisable to use EAGER
fetching, better user LAZY
fetching and build custom queries where they are needed. Check out https://vladmihalcea.com/eager-fetching-is-a-code-smell/ on this topic. Maybe Bootify.io may help you as well to create the database model.
Upvotes: 2