0

您好,我有一个包含对象集合的实体:

@Entity
public class ResourceType{
   @Id
   public Integer id;

  @ManyToMany(mappedBy = "resourcesTypes")
  private Set<Resource> resources = new HashSet<>();

}

如您所见,此实体包含资源集合

@Entity
public class Resource{

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "RESOURCE_TYPE_CROSS", joinColumns = { @JoinColumn(name = "RESOURCE_ID") }, inverseJoinColumns = { @JoinColumn(name = "RESOURCE_TYPE_ID", referencedColumnName = "ID") })
    private List<ResourceType> resourcesTypes = new ArrayList<>();
}

所以我想如果我得到所有资源的所有资源类型,这个集合在本地缓存中。

但是,如果我尝试持久化资源:

    @Override
    public ResourcesDTO createResource(ResourcesDTO resource) throws CreateResourceException {

    if (resource.getResourcesTypes().isEmpty()) {
        throw new CreateResourceException("Can not create resouce " + resource.getName()
                + " none resource types is set");                                      
    resourceDAO.create(map(resource));      

    log.debug("Created resource: " + r);
    resource.setId(r.getId());

    return resource

    }

如果我坚持使用 ResourcesTypes 的资源,接下来我将获得所有 ResourceTypes 实体管理器未找到新资源。但在我的交叉表 resource_type_cross 中一切正常。创建新资源后,我将尝试做类似的事情:

for(ResourceType rt : resource.getResourceTypes()){
    em.refresh(rt);
}

但它不能正常工作。在我将重新启动服务器后,一切都很好。但是为什么实体管理器不刷新资源类型??

这是我用来读取所有 ResourceTypes 的:

public ResourceType getAllResourceTypes(){
    em.createQuery("Select n from Resource n left join fetch n.children"); 
    return em.find(ResourceType.class, 0); //0 - ROOT

}

如下文章:http ://www.tikalk.com/java/load-tree-jpa-and-hibernate

主要问题是: 一侧创建或更新实体不更新另一侧,所以在我的情况下,我通过资源实体创建和更新资源类型,但我使用资源类型来获取所有资源。

4

1 回答 1

2

首先,您的 ManyToMany 映射存在问题。您已使双方单向访问同一个连接表,而不是双向访问。一方应控制映射,另一方设置为由拥有方映射。

其次,刷新 ResourceTypes 时是否刷新或提交了更改?通过在代码中设置引用而不是查询来刷新每个 ResourceType 可能更好地维护双方

于 2013-06-12T12:20:56.523 回答