Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 为什么Hibernate OneToMany映射必须显式刷新实体才能在单元测试中工作_Spring_Hibernate_One To Many - Fatal编程技术网

Spring 为什么Hibernate OneToMany映射必须显式刷新实体才能在单元测试中工作

Spring 为什么Hibernate OneToMany映射必须显式刷新实体才能在单元测试中工作,spring,hibernate,one-to-many,Spring,Hibernate,One To Many,我花了好几个小时才弄明白这种令人惊讶的行为,当我在一家公司的地图上进行测试时。 I rerea@Entity d阅读hibernate指南,仔细检查代码,测试设计,最后找出可能与hibernate缓存设计有关的根本原因。 以下是代码摘录: @Entity public class Organization { @Id @GeneratedValue(strategy=GenerationType.AUTO) private long id; @ManyToOne @JoinColumn(nam

我花了好几个小时才弄明白这种令人惊讶的行为,当我在一家公司的地图上进行测试时。 I rerea@Entity d阅读hibernate指南,仔细检查代码,测试设计,最后找出可能与hibernate缓存设计有关的根本原因。 以下是代码摘录:

@Entity
public class Organization {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;

@ManyToOne
@JoinColumn(name="cooperation_id")
private Cooperation cooperation;

@ManyToOne(optional=true)
@JoinColumn(name="organization_id", nullable=true)
private Organization upperLevel;

@OneToMany(mappedBy="upperLevel")
private Collection<Organization> subOrganizations = new ArrayList<Organization>();

@OneToOne(mappedBy="organization")
private TimeoffSetting timeoffSetting;

private String name;
...
@实体
公营班级组织{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
私人长id;
@许多酮
@JoinColumn(name=“cooperation\u id”)
私人合作;
@多通(可选=真)
@JoinColumn(name=“organization\u id”,nullable=true)
私营机构高层;
@OneToMany(mappedBy=“upperLevel”)
私有集合子组织=新建ArrayList();
@OneTONE(mappedBy=“组织”)
私有时间偏移时间偏移;
私有字符串名称;
...
JUNIT测试:

@PersistenceContext
private EntityManager entityManager

@Transactional
public void organization() {
    Organization organization_it = new Organization(cooperation, "IT");
    organization_it.setUpperLevel(organizationTop);
    organization_it = organizationRepository.save(organization_it);

    Organization organization_hr = new Organization(cooperation, "HR");
    organization_hr.setUpperLevel(organizationTop);
    organization_hr = organizationRepository.save(organization_hr);

    Organization organization_unix = new Organization(cooperation, "UNIX");
    organization_unix.setUpperLevel(organization_it);
    organization_unix = organizationRepository.save(organization_unix);

    boolean hasIt = false;
    boolean hasHr = false;
    Iterable<Organization> organizations = organizationRepository.findAll();
    for(Organization o: organizations) {
        entityManager.refresh(o);
        if (o.getName() == "cooperation") {
            org.junit.Assert.assertTrue(o.isTopLevel());
            org.junit.Assert.assertEquals(o.getSubOrganizations().size(), 2);

        }
    ...
@PersistenceContext
私有实体管理器实体管理器
@交易的
公共组织(){
组织机构=新组织(合作,简称“it”);
组织\u it.setUpperLevel(组织顶层);
organization\u it=organizationRepository.save(organization\u it);
组织机构=新组织(合作,简称“hr”);
组织机构设置层级(组织机构顶层);
organization\u hr=organizationRepository.save(organization\u hr);
Organization_unix=新组织(合作,unix);
组织机构unix.setUpperLevel(组织机构it);
organization\u unix=organizationRepository.save(organization\u unix);
布尔hasIt=false;
布尔hasHr=false;
Iterable organizations=organizationRepository.findAll();
对于(组织o:组织){
实体管理器刷新(o);
if(o.getName()=“合作”){
Assert.assertTrue(o.isTopLevel());
Assert.assertEquals(o.getSubOrganizations().size(),2);
}
...
请注意此处的entityManager.refresh(o)方法调用,如果我不刷新实体,则assertEquals(getSubOrganizations().size(),2)的OneToMany映射测试将导致失败。 通过谷歌搜索互联网,Spring的集成测试应该在编写ORM测试时更加谨慎。
有一篇文章可能很有用

很简单:您分配了它和HR的
上级组织
但忽略了通过将它和HR添加到顶层的
子组织
列表来保持对象图的一致性

对于Hibernate来说,这并不是一个真正的问题,因为您负责设置每个双向关联的所有者端,这就是Hibernate保持此关联所需的全部内容


但是,由于对象不是由Hibernate创建和填充的,而是由您创建和填充的,因此它们就是您创建的,当Hibernate负责创建和填充实体时,关联的双方是一致的。

谢谢你的评论。我有点理解Hibernate下发生了什么。但我的意图是这不是直接的。从某种角度来看,ORM缓存中的完整性没有得到适当维护如果不是这样的缓存层,我就不会碰到这个了。不管怎样,谢谢你的解释。