Spring repository + FetchType.LAZY attribute got exception: com.impetus.kundera.proxy.LazyInitializationException: Unable to load Proxy Collection.
bedinsky opened this issue · comments
Caused by: com.impetus.kundera.proxy.LazyInitializationException: Unable to load Proxy Collection. This happens when you access a lazily loaded proxy collection in an entity after entity manager has been closed.
at com.impetus.kundera.proxy.collection.AbstractProxyBase.eagerlyLoadDataCollection(AbstractProxyBase.java:111) ~[kundera-core-3.12.jar:na]
at com.impetus.kundera.proxy.collection.AbstractProxyCollection.iterator(AbstractProxyCollection.java:221) ~[kundera-core-3.12.jar:na]
at com.impetus.kundera.proxy.collection.ProxySet.iterator(ProxySet.java:118) ~[kundera-core-3.12.jar:na]
at it.thisone.iotter.persistence.service.EmptyDbInitializator.checkDb(EmptyDbInitializator.java:126) ~[vaadin8-iotter-backend-3.0-SNAPSHOT.jar:na]
at it.thisone.iotter.persistence.service.EmptyDbInitializator.afterPropertiesSet(EmptyDbInitializator.java:111) ~[vaadin8-iotter-backend-3.0-SNAPSHOT.jar:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
... 21 common frames omitted
I got the exception using a spring service.
Service retrieves a list of TUser and it tries to read a collection of TRole (annotated with FetchType.LAZY) associated to each TUser
Exception is clear and it does not happen if I execute the same operations with an EntityManager directly.
I do not think it is a problem of spring service since it is working correctly with EclipseLink
Looking at logs, entitymanager is close after retrieving list of TUser consequently it is not possible to retrieve a FetchType.LAZY collection
15:23:40.659 [localhost-startStop-1] DEBUG c.i.k.persistence.EntityManagerImpl - Created EntityManager for persistence unit : cassandra_pu
15:23:40.985 [localhost-startStop-1] INFO com.impetus.kundera.query.QueryImpl - On getResultList() executing query: select be from TUser be
15:23:40.985 [localhost-startStop-1] DEBUG c.i.client.cassandra.query.CassQuery - Populating entities for Cassandra query select be from TUser be.
15:24:24.399 [localhost-startStop-1] DEBUG o.s.o.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
If I try to reattach EntityManager to a TUser entity with a merge and retrieve lazy collection, I get a similar exception
Please help me to understand what I'm doing wrong
I'm using @config with
@EnableAspectJAutoProxy(proxyTargetClass=true)
and @PersistenceContext to inject entitymanager
classes
@Entity
@Table(name = "t_role")
public class TRole {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Id
@Column(name = "name", nullable = false)
private String name;
}
@Table(name = "t_user")
public class TUser {
@Id
@Column(name = "name", nullable = false)
private String name;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "t_user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<TRole> roles = new HashSet<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<TRole> getRoles() {
return roles;
}
public void setRoles(Set<TRole> roles) {
this.roles = roles;
}
}
@Entity
@Table(name = "t_group")
public class TGroup {
@Id
@Column(name = "id", nullable = false)
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "t_group_role", joinColumns = @JoinColumn(name = "group_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<TRole> roles = new HashSet<>();
public Set<TRole> getRoles() {
return roles;
}
public void setRoles(Set<TRole> roles) {
this.roles = roles;
}
}
persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
https://raw.github.com/impetus-opensource/Kundera/Kundera-2.0.4/kundera-core/src/test/resources/META-INF/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="cassandra_pu">
<provider>com.impetus.kundera.KunderaPersistence</provider>
<class>xxx.persistence.model.TGroup</class>
<class>xxx.persistence.model.TRole</class>
<class>xxx.persistence.model.TUser</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="kundera.nodes" value="172.168.1.131" />
<property name="kundera.port" value="9042" />
<property name="kundera.keyspace" value="kunderaexamples" />
<property name="kundera.dialect" value="cassandra" />
<property name="kundera.ddl.auto.prepare" value="create" />
<property name="kundera.client.lookup.class"
value="com.impetus.kundera.client.cassandra.dsdriver.DSClientFactory" />
</properties>
</persistence-unit>
</persistence>
maven dependencies
<dependencies>
<dependency>
<groupId>com.impetus.kundera.client</groupId>
<artifactId>kundera-cassandra</artifactId>
<version>3.12</version>
</dependency>
<dependency>
<groupId>com.impetus.kundera.client</groupId>
<artifactId>kundera-cassandra-ds-driver</artifactId>
<version>3.12</version>
</dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-mapping</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-extras</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.0</version>
</dependency>
</dependencies>
Hi @bedinsky,
Is this working fine with spring and FetchType.EAGER?
Sure, I'm using FetchType.EAGER as workaround.