2017-03-21 65 views
4

我有一个错误:nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.Model.entities, could not initialize proxy - no SessionHibernate:LazyInitializationException:未能懒惰地初始化一个角色集合。无法初始化代理 - 没有会话

Model实体:

class Model { 
... 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "model", orphanRemoval = true) 
    @Cascade(CascadeType.ALL) 
    @Fetch(value = FetchMode.SUBSELECT) 
    public Set<Entity> getEntities() { 
     return entities; 
    } 

    public void addEntity(Entity entity) { 
     entity.setModel(this); 
     entities.add(entity); 
    } 

} 

而且我有一个服务类:

@Service 
@Transactional 
class ServiceImpl implements Service { 
    @Override 
    public void process(Model model) { 
     ... 
     model.addEntity(createEntity()); 
     ... 
    } 
} 

我从呼叫服务另一种服务方式:

@Override 
@JmsListener(destination = "listener") 
public void handle(final Message message) throws Exception { 
    Model model = modelService.getById(message.getModelId()); 
    serviceImpl.process(model); 
    modelService.update(model); 
} 

但是,当我试图调用此方法时,我在entities.add(entity);行发生异常,当我拨打model时拨打getEntities()也会发生同样的异常。 我检查了事务管理器,它的配置正确,并且在这一步中存在事务。此外,我已经检查吨连接到这个异常,但没有用的stackoverflow的答案。

可能是什么原因呢?

+0

当你说“_transaction存在于这个step_”时,你的意思是说你已经检查过一个事务真的是开放的,就像使用http://stackoverflow.com/a/42584751/3517383? – gabrielgiussi

+0

@gabrielgiussi是 –

+0

实体是一个新对象吗?如果是这种情况,则必须先将实体对象保存在数据库中,然后才能将其添加到实体列表中。 – Dimitri

回答

4

看来,模型是一个独立的实体。

尝试合并,并在合并实例执行操作:

@Override 
public void process(Model model) { 
    ... 
    Model mergedModel = session.merge(model); 

    mergedModel.addEntity(createEntity()); 
    ... 
} 
+0

事实上,或者在调用所有其他服务的初始服务中打开事务。 – gabrielgiussi

+1

其实我不想使用会话对象。在调用过程之前,我正在做modelService.getModelById(modelId);它返回数据库中的对象 –

+1

好吧,但这是我做的假设在一个单独的事务..一旦你调用过程方法模型已经是一个分离的实体和持久性提供商不再管理它。你必须把它合并回来。或者直接在流程方法中进行查询。 –

1

因此,作为@Maciej科瓦尔斯基后第一@Transactional读我的model提到它已经在deatached状态,并呼吁从失败的另一个@Transactional方法得到entitiesLazyInitializationException

我已经改变了我的服务一点在同一事务中获得model从数据库:

@Service 
@Transactional 
class ServiceImpl implements Service { 
    @Override 
    public void process(long modelId) { 
     ... 
     Model model = modelDao.get(modelId); 
     model.addEntity(createEntity()); 
     ... 
    } 
} 

现在一切正常。

+0

你应该标记Maciej答案是正确的。 – gabrielgiussi

相关问题