Моя проблема заключается в том, что спящий режим извлечения нуль в значении @OneToMany Set organizationMemberCollection
при извлечении экземпляра по объекту:Hibernate получить нуль для сбора OneToMany
UserAccount.java:
@Entity
@Table(name="USER_ACCOUNT")
public class UserAccount {
@Id
@Column(name = "id", nullable = false)
@SequenceGenerator(name = "generator", sequenceName = "USER_ACCOUNT_id_seq", allocationSize=1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "generator")
private Long id;
@Column(name = "EMAIL", nullable = false)
private String email;
@Column(name = "PASSWORD_HASH")
private String passwordHash;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "userAccount")
private Set <OrganizationMember> organizationMemberCollection;
...
/*
* getters and setters
*/
}
Вот объект, который «владеет» ассоциацией:
ОрганизацияMember.java:
@Entity
@Table(name="ORGANIZATION_MEMBER")
public class OrganizationMember{
@Id
@Column(name = "id", nullable = false)
@SequenceGenerator(name = "generator", sequenceName = "ORGANIZATION_MEMBER_id_seq", allocationSize=1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "generator")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "USER_ACCOUNT_ID", nullable = false)
private UserAccount userAccount;
...
/*
* getters and setters
*/
}
В этом приложении мы имеем два различных configuations:
Производство, где Hibernate подключается к базе данных PostgreSQL. Вот SessionFactory конфигурация для прод:
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="hibernateProperties"> <props> <prop key="hibernate.jdbc.batch_size">10</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.cglib.use_reflection_optimizer">false</prop> </props> </property> ... </bean>
Test, где Hibernate является conencted Ань в памяти базы данных HSQLDB:
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop> <prop key="hibernate.show_sql">false</prop> <prop key="hibernate.cglib.use_reflection_optimizer">false</prop> <prop key="hibernate.hbm2ddl.auto">create-drop</prop> <prop key="hibernate.cache.use_second_level_cache">false</prop> <prop key="hibernate.cache.use_query_cache">false</prop> </props> </property> ... </bean>
Этот вопрос только показать в конфигурации тестирования; В производственной конфигурации все идет хорошо, и я могу получить коллекцию. Однако, когда я получаю UserAccount в тестовой конфигурации, я получаю null
в свойстве organizationMemberCollection
(Не пустой набор).
После нескольких часов исследований с помощью документов google и Hibernate я до сих пор не нашел сообщений, связанных с одной и той же проблемой/поведением, поэтому я потерял битлу, и помощь будет принята с благодарностью!
Я могу, конечно, предоставить дополнительную информацию, если это необходимо, спасибо!
Edit:
Тест higlighting проблему:
@Test
@Transactional
public void testFindUserAccount_OrganizationMemberCollectionFetching() {
assertNotNull(userAccountDao.findUserAccount("[email protected]")); //NoProblem
assertNotNull(userAccountDao.findUserAccount("[email protected]").getCabinetMemberCollection()); //Fails
}
Со следующим findUserAccount
дао
public UserAccount findUserAccount(String email) {
if (email == null) {
return null;
}
UserAccount userAccount = (UserAccount) this.sessionFactory
.getCurrentSession().createCriteria(UserAccount.class)
.add(Restrictions.eq("email", email).ignoreCase())
.uniqueResult();
if (userAccount == null) {
throw new ObjectNotFoundException("UserAccount.notFound");
} else {
return userAccount;
}
}
вы получаете нуль, потому что у вас нет какой-либо организацииMemberCollection, связанной с вашим userAccount. Можете ли вы предоставить код вашего теста? возможно, вы забыли вызвать метод setUserAccount перед сохранением объекта OrganizationMember –
Спасибо за быстрый ответ, я думаю, что в такой ситуации Hibernate вернет мой UserAccount с пустым Set, а не с нулевым значением, но, возможно, я ошибаюсь. Я уверен, что у OrganizationMember есть ссылка на учетную запись пользователя, потому что db заполняется перед тестами. И когда я получаю объект OrganizationMember, объект, возвращаемый спящим режимом, имеет ссылку на UserAccount. – Tom
Вы уверены, что контекст персистентности не близок, когда вы вызываете getOrganizationMemberCollection в своем тесте? Если бы мы могли видеть код, возможно, это могло бы помочь –