Tom*_*Tom 3 java hibernate one-to-many hibernate-onetomany
我的问题是,hibernate 在获取以下对象上的实例时的值中检索null@OneToMany Set organizationMemberCollection:
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
*/
}
Run Code Online (Sandbox Code Playgroud)
这是"拥有"该关联的对象:
OrganizationMember.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
*/
}
Run Code Online (Sandbox Code Playgroud)
在这个应用程序中,我们有两种不同的配置:
生产,Hibernate连接到PostgreSQL数据库.这是prod的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>
测试,其中Hibernate连接到内存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属性(不是空集).
通过谷歌和Hibernate的文档进行了几个小时的研究后,我仍然没有找到任何与相同问题/行为有关的帖子,所以我会失去一点点帮助,我将不胜感激!
如果需要,我当然可以提供更多信息,谢谢!
测试高亮问题:
@Test
@Transactional
public void testFindUserAccount_OrganizationMemberCollectionFetching() {
assertNotNull(userAccountDao.findUserAccount("user1@test.fr")); //NoProblem
assertNotNull(userAccountDao.findUserAccount("user1@test.fr").getCabinetMemberCollection()); //Fails
}
Run Code Online (Sandbox Code Playgroud)
随着以下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;
}
}
Run Code Online (Sandbox Code Playgroud)
问题是数据库填充和测试在同一事务中运行,并且在这两个步骤之间没有清除hibernate缓存.
结果是,hibernate并没有真正将请求发送到数据库,而是命中了缓存并返回了对象而没有与映射关系进行任何连接.
可能的解决方案是:
SessionFactory.getCurrentSession().clean();在人口之后清理会话.(如果需要,请刷新会话:) SessionFactory.getCurrentSession().flush();.每种可能性都会强制下一个查询真正命中数据库,因此将发生连接并且映射的Collection将包含所需数据(如果连接没有结果,则为空,但无论如何Collection都没有null值).
在我看来,第一种解决方案更好,因为如果测试中出现问题,它不会回滚整个人口.
| 归档时间: |
|
| 查看次数: |
4632 次 |
| 最近记录: |