gpt4 book ai didi

java - Hibernate 为 OneToMany 集合检索 null

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:41:45 25 4
gpt4 key购买 nike

我的问题是 hibernate 在 @OneToMany Set organizationMemberCollection 的值中检索 null在以下对象上获取实例时:

用户帐户.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
*/
}

这是“拥有”关联的对象:

组织成员.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
*/
}

在这个应用程序中,我们有两种不同的配置:

  • 生产,其中 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 时,我得到了 nullorganizationMemberCollection属性(不是空集)。

通过谷歌和 Hibernate 的文档进行了几个小时的研究后,我仍然没有找到与同一问题/行为相关的任何帖子,所以我有点迷茫,我们将不胜感激!

如果需要,我当然可以提供更多信息,谢谢!

编辑:

测试突出问题:

@Test
@Transactional
public void testFindUserAccount_OrganizationMemberCollectionFetching() {

assertNotNull(userAccountDao.findUserAccount("user1@test.fr")); //NoProblem
assertNotNull(userAccountDao.findUserAccount("user1@test.fr").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;
}
}

最佳答案

问题是数据库填充和测试在同一个事务中运行,并且在这两个步骤之间没有清理 hibernate 缓存。

结果是 hibernate 并没有真正触发对数据库的请求,而是访问了缓存并返回了对象,而没有对映射关系进行任何连接。

可能的解决方案是:

  • 在不同的事务中填充数据库。
  • 在填充后清除 session SessionFactory.getCurrentSession().clean();。 (如果需要,请先刷新 session :SessionFactory.getCurrentSession().flush();)。

每种可能性都会迫使下一个查询真正命中数据库,因此会发生连接并且映射的集合将包含想要的数据(或者如果连接没有结果则为空,但在任何情况下集合都不会具有 null 值)。

在我看来,第一个解决方案要好得多,因为如果测试出现问题,它不会回滚整个群体。

关于java - Hibernate 为 OneToMany 集合检索 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36184002/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com