简体   繁体   English

LazyInitializationException

[英]LazyInitializationException

I have the entity Profile with a set of ProfileConstraintSetEntity 我有一组带有ProfileConstraintSetEntity的实体Profile

@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: ProfileConstraintSetEntity如下所示:

@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: GroupConstraintEntity看起来像这样:

@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. 两个实体都具有hashcode()和equals()方法。 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: 这里的DAO函数获取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: 它仅执行第一个syso测试,并使用以下堆栈跟踪退出:

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: UPDATE * :如果我在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. 但是我不明白。

Change the @OneToMany mapping in ProfileEntity to this: 更改@OneToMany在映射ProfileEntity这样:

@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 . 保持默认的获取模式为FetchType.LAZY If you use EAGER fetching, it will always fetch the constraintSets even though that is not needed. 如果您使用EAGER提取,即使不需要,它也将始终提取constraintSets

Now wherever needed you can override this default behavior in code, so that constraintSets can be loaded along with the ProfileEntity . 现在,无论何时需要,您都可以在代码中覆盖此默认行为,以便可以将constraintSetsProfileEntity一起加载。 You can replace getProfile method code to this: 您可以将getProfile方法代码替换为此:

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 . 这将获取所选ProfileEntity constraintSets ProfileEntity

EDIT : 编辑

In the ProfileConstraintSetEntity class, change the mapping of Set<GroupConstraintEntity> constraints : ProfileConstraintSetEntity类中,更改Set<GroupConstraintEntity> constraints的映射:

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

you don't need to have @JoinColumn annotation with constraints . 您不需要具有constraints @JoinColumn注解。

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. 您在GroupConstraintEntity具有的以下映射表示,您在tbl_profile_group_constraint具有一列profile_constraint_or_id ,用于存储关系。

@JoinColumn(name = "profile_constraint_or_id", insertable = false, updatable = false)
private ProfileConstraintSetEntity constraintSet;

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);

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! 谢谢您的帮助!

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 . 解决此问题的正确方法是使用OpenSessionInViewFilter

Here is a tutorial on how to do that . 这是有关如何执行此操作的教程

you can try to add in web.xml 您可以尝试添加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 来源http://blog.gmorales.net/2012/03/how-to-solve-orghibernatelazyinitializa.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM