0

I have the entity Profile with a set of ProfileConstraintSetEntity

@Entity
@Table(name = "tbl_group_profile")
public class ProfileEntity {
        @Id
        @GeneratedValue
        @Column(name = "group_profile_id")
        private long id;

        @Column(name = "title")
        private String title;

        @OneToMany(mappedBy = "profile")
        private Set<ProfileConstraintSetEntity> constraintSets = new HashSet<ProfileConstraintSetEntity>();

The ProfileConstraintSetEntity looks like this:

@Entity
@Table(name = "tbl_profile_constraint_or")
public class ProfileConstraintSetEntity {
    @Id
    @GeneratedValue
    @Column(name = "profile_constraint_or_id")
    private long id;

    @ManyToOne
    @JoinColumn(name = "group_profile_id", insertable = false, updatable = false)
    private ProfileEntity profile;

    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(name = "profile_constraint_or_id")
    private Set<GroupConstraintEntity> constraints;

The GroupConstraintEntity looks like this:

@Entity
@Table(name = "tbl_profile_group_constraint")
public class GroupConstraintEntity {

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "profile_constraint_or_id", insertable = false, updatable = false)
    private ProfileConstraintSetEntity constraintSet;

    @ManyToOne
    @JoinColumn(name = "cp_group_id", insertable = false, updatable = false)
    private CpGroupEntity group;

    @Column(name = "constraint_type")
    @Enumerated(EnumType.STRING)
    private GroupConstraintType type;

Both entities hav a hashcode() and an equals() method. But if I execute this:

// Get profile entity
ProfileEntity entity = profileDAO.getProfile(id);
// Syso for test
System.out.println(entity.getId());
System.out.println(entity.getTitle());

for (ProfileConstraintSetEntity profileConstraintSetEntity : entity.getConstraintSets()) {
    // Syso for test
    System.out.println(profileConstraintSetEntity.getId());
    System.out.println(profileConstraintSetEntity.getProfile().getId());
}

Here the DAO function to get the Profile:

public ProfileEntity getProfile(long id) throws NoSuchProfileException {
    try {
        ProfileEntity result = entityManager.getReference(ProfileEntity.class, id);

        // Trigger EntityNotFoundException now, in case of lazy fetching
        result.getTitle();

        return result;
    } catch (EntityNotFoundException e) {
        throw new NoSuchProfileException("Unknown group profile ID " + id);
    }
}

it only executes the first syso test and quits with the following stack trace:

Okt 28, 2013 11:23:23 AM com.sun.jersey.spi.container.ContainerResponse mapMappableContainerException
SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
org.hibernate.LazyInitializationException: illegal access to loading collection
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:377)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:113)
at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:428)
at net.erouting.db.groups.ProfileConstraintSetEntity.hashCode(ProfileConstraintSetEntity.java:59)
at java.util.HashMap.hash(HashMap.java:351)
at java.util.HashMap.put(HashMap.java:471)
at java.util.HashSet.add(HashSet.java:217)
at java.util.AbstractCollection.addAll(AbstractCollection.java:334)
at org.hibernate.collection.internal.PersistentSet.endRead(PersistentSet.java:346)
at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:243)
at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:233)
at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:210)
at org.hibernate.loader.Loader.endCollectionLoad(Loader.java:1018)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1006)
at org.hibernate.loader.Loader.doQuery(Loader.java:874)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.loadEntity(Loader.java:2033)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:82)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:72)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3719)
at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:449)
at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:418)
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:204)
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:143)
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1079)
at org.hibernate.internal.SessionImpl.immediateLoad(SessionImpl.java:994)
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:158)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:195)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at net.erouting.db.groups.ProfileEntity_$$_javassist_17.getTitle(ProfileEntity_$$_javassist_17.java)
at net.erouting.db.groups.ProfileDAO.getProfile(ProfileDAO.java:22)
at net.erouting.admin.ProfileManager.getProfile(ProfileManager.java:55)
at net.erouting.admin.ProfileManager$$FastClassByCGLIB$$e2da60df.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
at net.erouting.admin.ProfileManager$$EnhancerByCGLIB$$625d6c76.getProfile(<generated>)
at net.erouting.api.Profile.getProfile(Profile.java:85)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205)
at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1483)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1414)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1363)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1353)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:414)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:708)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.www.DigestAuthenticationFilter.doFilter(DigestAuthenticationFilter.java:209)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

I tried to use

(fetch = FetchType.EAGER) and (fetch = FetchType.LAZY)
@PersistenceContext(type = PersistenceContextType.EXTENDED)

at the collections of the entities

What am I doing wrong?

UPDATE *: if I comment out this in the ProfileConstraintSetEntity:

//  @OneToMany(fetch = FetchType.EAGER)
//  @JoinColumn(name = "profile_constraint_or_id")
//  private Set<GroupConstraintEntity> constraints;

Both sys test blocks are executed. So I think the Error must be in the configration of this propperty. But I don't get it.

tshepang
  • 12,111
  • 21
  • 91
  • 136
EvilKarter
  • 267
  • 7
  • 22
  • 1
    Use only FetchType.EAGER and see. You get the error when you try to retrieve the child objects and you have retrieved the parent with fetch type LAZY. Try with eager fetch. This can also be set before query execution. – Abhijith Nagarajan Oct 28 '13 at 10:34
  • Wenn I add (fetch = FetchType.EAGER) to all collections in the entities I get the same error with the expection that the first syso test is not executed. – EvilKarter Oct 28 '13 at 10:43
  • Can you put in your DAO code and also the updated configuration. No need to initialize your collection with new HashSet(); If I have understood correctly, you are getting error from second set of sysout (statements inside the for loop) – Abhijith Nagarajan Oct 28 '13 at 10:46
  • Edited DAO code and updated configuration for entitites. – EvilKarter Oct 28 '13 at 10:50
  • 1
    Is there a good reason why you didn't map the bidirectional association using the standard way: `@OneToMany(mappedBy = "profile")`? My guess is that this is the cause of your problems. – JB Nizet Oct 28 '13 at 10:52
  • 1
    Remove @JoinColumn and change to @OneToMany(mappedBy = "profile") – Sergey Morozov Oct 28 '13 at 10:55
  • Can you see what are the SQL's generated at the backend? You might get this error even if the actual child records are missing or may also because of joinColumn. See below link https://forum.hibernate.org/viewtopic.php?f=1&t=962889 – Abhijith Nagarajan Oct 28 '13 at 10:56
  • If I use @OneToMany(mappedBy = "profile") instead of @JoinColumn the first syso test is executed again. So what have I to do at the ProfileConstraintSetEntity ? – EvilKarter Oct 28 '13 at 11:00

5 Answers5

0

Change the @OneToMany mapping in ProfileEntity to this:

@Entity
@Table(name = "tbl_group_profile")
public class ProfileEntity {
...
@OneToMany(mappedBy = "profile", fetch = FetchType.LAZY)
private Set<ProfileConstraintSetEntity> constraintSets;
....
}

Keep default fetch mode as FetchType.LAZY. If you use EAGER fetching, it will always fetch the constraintSets even though that is not needed.

Now wherever needed you can override this default behavior in code, so that constraintSets can be loaded along with the ProfileEntity. You can replace getProfile method code to this:

Query query = entityManager.createQuery("select p from ProfileEntity p " +
            "left join fetch p.constraintSets where p.id=:id");
query.setParameter("id", id);
ProfileEntity profileEntity = (ProfileEntity) query.getResultList().get(0);

this will fetch constraintSets of the selected ProfileEntity.

EDIT:

In the ProfileConstraintSetEntity class, change the mapping of Set<GroupConstraintEntity> constraints :

@OneToMany(fetch = FetchType.EAGER, mappedBy = "constraintSet")
private Set<GroupConstraintEntity> constraints;

you don't need to have @JoinColumn annotation with constraints.

The below mapping that you have in GroupConstraintEntity says that you have a column profile_constraint_or_id in tbl_profile_group_constraint which stores the relationship.

@JoinColumn(name = "profile_constraint_or_id", insertable = false, updatable = false)
private ProfileConstraintSetEntity constraintSet;
Debojit Saikia
  • 10,532
  • 3
  • 35
  • 46
  • If I make the changes than I get this: javax.persistence.PersistenceException: org.hibernate.LazyInitializationException: illegal access to loading collection. And no of my test syso were executed – EvilKarter Oct 28 '13 at 11:21
0

Have you tried

ProfileEntity result =  (ProfileEntity) entityManager.find(ProfileEntity.class, id);
result.getTitle();
result.getConstraintSets().size();
return result;

instead of

entityManager.getReference(ProfileEntity.class, id);

Atul
  • 2,673
  • 2
  • 28
  • 34
  • I tried it and got the same error as alyways. But the first test syso lock was executed – EvilKarter Oct 28 '13 at 11:40
  • In your DAO getProfile method, after entityManager.find(ProfileEntity.class, id); result.getTitle(); write result.getConstraintSets() and then write the return result – Atul Oct 28 '13 at 11:58
  • I don't know what you mean? – EvilKarter Oct 28 '13 at 11:59
  • try accessing getConstraintSets in your DAO method before returning the result. – Atul Oct 28 '13 at 12:00
  • No it still doesn't work. I Think the error is in the declaration of constraints in the ProfileConstraintSetEntity. But I don't get it. If I comment it out, it works but I need the contraints. – EvilKarter Oct 29 '13 at 07:20
0

I have found the error.

When I use Lists instead of Sets it works quite fine. But I don't know why. Perhaps someone can explain me, what I have to do, that it althouhj works with sets.

Thank you for your help!

EvilKarter
  • 267
  • 7
  • 22
0

This error means that you’re trying to access a lazily-loaded property or collection, but the hibernate session is closed or not available.

The correct way to fix this is to use an OpenSessionInViewFilter.

Here is a tutorial on how to do that.

Mark Parnell
  • 9,175
  • 9
  • 31
  • 36
0

you can try to add in web.xml

<filter>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

bud make sure about whats the impact in your application

source http://blog.gmorales.net/2012/03/how-to-solve-orghibernatelazyinitializa.html

demian
  • 632
  • 7
  • 14