JPA @ManyToMany协会似乎只是单向工作

时间:2014-01-07 18:04:45

标签: java hibernate jpa

我已经定义了以下关联:

public class Location
...
@ManyToMany(mappedBy="locations")
    private List<KMLFolder> kmlFolderList;

public class KMLFolder
...
@ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name="LOCATION_KMLFOLDER",
        joinColumns={@JoinColumn(name="KMLFOLDER_ID", referencedColumnName="ID")},
        inverseJoinColumns={@JoinColumn(name="LOCATION_ID", referencedColumnName="ID")}
            )
    private List<Location> locations = new ArrayList<Location>();

这是一个单元测试。前3个断言通过,但最后一个断言失败:

@Test
@Transactional
public void thatFolderLocationAssociationTableIsWorking() {
    Location l1 = new DomesticLocation();
    l1.setDeptName("Test name 1");
    Location l2 = new DomesticLocation();
    l2.setDeptName("Test name 2");

    KMLFolder k1 = new KMLFolder();
    k1.setName("Test name 1");

    List<Location> locations = new ArrayList<Location>();
    locations.add(l1);
    locations.add(l2);
    k1.setLocations(locations);

    kmlFolderServiceImpl.save(k1);

    assertEquals("Test name 1", kmlFolderServiceImpl.find(1L).getLocations().get(0).getDeptName());
    assertEquals("Test name 2", kmlFolderServiceImpl.find(1L).getLocations().get(1).getDeptName());
    assertNotNull(locationServiceImpl.findAll().get(0));

    //Failing Assertion
    assertNotNull(locationServiceImpl.find(1L).getKmlFolderList());

}

有什么想法为什么这可能不会持续正确?感谢。

1 个答案:

答案 0 :(得分:1)

所有代码都在一个事务中执行。因此,Hibernate会话以及第一级缓存对于测试中的所有代码都是唯一的。您的代码初始化关联的一侧而不初始化另一侧。因此,您创建了一个不连贯的对象图,它存储在第一级缓存中。

当使用Hibernate使用finder加载实体时,Hibernate会返回缓存中的非连贯实体。如果你有一个用于保存的事务,另一个用于获取实体,Hibernate将为第二个事务使用一个新的空缓存,并以一致的方式从表中找到的数据填充实体。 / p>