Impetus / kundera

A JPA 2.1 compliant Polyglot Object-Datastore Mapping Library for NoSQL Datastores.Please subscribe to:
http://groups.google.com/group/kundera-discuss/subscribe
Apache License 2.0
903 stars 233 forks source link

Spring repository + FetchType.LAZY attribute got exception: com.impetus.kundera.proxy.LazyInitializationException: Unable to load Proxy Collection. #1016

Open bedinsky opened 6 years ago

bedinsky commented 6 years ago
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>
devender-yadav commented 6 years ago

Hi @bedinsky,

Is this working fine with spring and FetchType.EAGER?

bedinsky commented 6 years ago

Sure, I'm using FetchType.EAGER as workaround.