【发布时间】:2013-05-20 13:32:17
【问题描述】:
在应用程序中运行多个线程时,我遇到了 Spring 和 Hibernate 的一个奇怪问题。我正在使用 spring 3.2.0.RELEASE 和休眠 4.1.12.Final。问题是对于某些对象,当从数据库中检索它们时,检索成功,但未设置所有映射集合。这是我的回购的一个例子:
@Repository("fooRepository")
public class FooRepository {
private static final Logger log = Logger.getLogger(FooRepository.class);
@Autowired
private SessionFactory sessionFactory;
@Override
@Transactional
public Foo retrieve(final Long id) {
Foo instance = (Foo) sessionFactory.getCurrentSession().get(Foo.class, id);
for (CollectionMember member : instance.getCollectionMembers()) {
log.debug(member.getId());
}
return instance;
}
对于某些对象,此方法在尝试访问 CollectionMember 列表时总是会抛出以下错误:
Caused by: java.lang.NullPointerException
at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:501)
问题是 session.get() 调用为所有延迟加载的集合创建 PersistentBag 对象,但从不设置内容。这仅在启用多线程时发生。谁能解释为什么会这样?
编辑: 这是 foo 类的相关部分:
@Entity
@Table(name = "FOO")
@XmlRootElement(name = "foo")
public class Foo {
@EmbeddedId
private FooPK id;
@OneToMany
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumns({
@JoinColumn(name = "COLLECTION_ID", referencedColumnName = "COLLECTION_ID"),
@JoinColumn(name = "FOO_ID", referencedColumnName = "FOO_ID")})
private List<CollectionMember> collectionMembers = new ArrayList<CollectionMember>();
还有 CollectionMember 类:
@Entity
@Table(name = "COLLECTION_MEMBER")
@XmlRootElement(name = "collectionMember")
public class CollectionMember {
@EmbeddedId
private CollectionMemberPK primaryKey;
@ManyToOne
@JoinColumn(name = "COLL_CODE")
private CollectionCode collectionCode;
【问题讨论】:
-
提供完整的堆栈跟踪(即使它有点冗长)可能有助于更好地解决问题。
-
您可以发布 Foo 和 CollectionMember 类,或者至少是显示映射注释的位(或者如果您使用 xml 配置,则发布 hbm.xml)
-
我无法发布完整的堆栈跟踪,除非我手动更改了一堆包名称,这样你就无法知道它来自哪里。如果你真的认为完整的堆栈跟踪会提供更多信息,我会这样做,但我不相信你需要的比你已经拥有的更多,不过我会添加映射。
-
如果 NPE 在
toString()中是否意味着它是由log.debug(member.getId());抛出的?如果不是,是否有可能在处理不同的异常期间引发此异常?此外,有关您的事务管理配置的信息也可能很有趣 - 您是否使用@EnableTransactionalManagement? -
请放完整的堆栈跟踪
标签: java multithreading spring hibernate lazy-loading