アプリケーションで複数のスレッドを実行すると、Spring と Hibernate で奇妙な問題が発生します。春の 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;