Hibernate与额外列的多对多关系

时间:2014-12-06 03:36:23

标签: java spring hibernate

我有像这样的数据库结构。它适用于我的应用程序中的用户访问控制。

 UserGroup
 ==========
 id (PK)
 code
 name


 HakAkses
 ==========
 id(PK)
 UserGroup_id (FK)
 Akses_id (FK) 
 action_create
 action_read
 action_update
 action_delete


 Akses
 ==========
 id(PK)
 code

我按照这个

制作hibernate注释
@Entity
@Table(name = "[Master].[UserGroup]")
public class UserGroup implements Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(unique = true, length = 10)
    private String kode;
    private String nama;

    @OneToMany(mappedBy = "userGroup")
    private Set<HakAkses> hakAksesSet;
}

@Entity
@Table(name = "[master].[HakAkses]")
public class HakAkses implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "UserGroup_id", nullable = false)
    private UserGroup userGroup;

    @ManyToOne
    @JoinColumn(name = "Akses_id", nullable = false)
    private Akses akses;

    @Column(name = "action_create")
    private boolean canCreate;
    @Column(name = "action_read")
    private boolean canRead;
    @Column(name = "action_update")
    private boolean canUpdate;
    @Column(name = "action_delete")
    private boolean canDelete;
}

@Entity
@Table(name = "[master].[Akses]")
public class Akses implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(unique = true)
    private String kode;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "akses")
    private List<HakAkses> hakAksesSet;
}

然后我用我的代码尝试了这个代码

UserGroup userGroup = new UserGroup(kode, nama);
userGroup.setHakAksesSet(new HashSet<HakAkses>(hakAksesList));
this.controller.save(userGroup);

但是当我运行测试程序时,数据只保存在数据库中的UserGroup数据中。 我的hibernate注释有问题吗?

谢谢

2 个答案:

答案 0 :(得分:0)

这是因为父实体上缺少级联注释。看看这是否有帮助

@Table(name = "[Master].[UserGroup]")
public class UserGroup implements Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(unique = true, length = 10)
    private String kode;
    private String nama;

    @OneToMany(mappedBy = "userGroup", cascade = CascadeType.ALL)
    private Set<HakAkses> hakAksesSet;
}

答案 1 :(得分:0)

您的地图使用 mappedBy ,除其他设置外,还会将 inverse="true" 设置注入一对多端。在这里阅读更多相关信息:

简而言之,这意味着,Hibernate被指示:另一个(多对一)端将关心持久性。另外,请尝试在文档

中查看此示例

23.2. Bidirectional one-to-many

这个例子显示了反向行动,一些必要的引用:

  

...现在Child实体正在管理链接的状态,我们告诉集合不要更新链接。我们使用inverse属性来执行此操作:

<set name="children" inverse="true">
    <key column="parent_id"/>
    <one-to-many class="Child"/>
</set>
  

以下代码将用于添加新的Child:

Parent p = (Parent) session.load(Parent.class, pid);
Child c = new Child();
c.setParent(p);
p.getChildren().add(c);
session.save(c);
session.flush();
  

现在只会发布一个SQL INSERT。

那么我们在那里看到了什么?

  • 反向设置是我们需要的。它提高了性能(由于mappedBy我们拥有它)
  • 但仅在one-to-many方面设置关系是不够的。我们必须为每个孩子设置

所以,你应该扩展这个:

UserGroup userGroup = new UserGroup(kode, nama);
userGroup.setHakAksesSet(new HashSet<HakAkses>(hakAksesList));
// this is not enough - we also MUST 
// FOR each HakAkses in the  list 
// SET a Parent, i.e hakAksses.setUserGroup(userGroup)

最后,(几乎)总是应该开启级联。人们不应该手动关注:

@OneToMany(mappedBy = "userGroup", cascade = CascadeType.ALL)