使用级联的Hibernate OneToMany映射

时间:2016-01-19 14:17:48

标签: java hibernate jpa

我会说得简单。我有User class和Privilege类。用户拥有许多权限。

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
private Set<Privilege> privileges;

权限只有一个用户。

@ManyToOne
@JoinColumn(name = "user_id", nullable = false)
private User user;

如您所见,我已将CascadeType指定为ALL,但每当我想要保留我的用户时:

    Set<Privilege> privs = new HashSet<>();
    Privilege priv = new Privilege("anything");
    //priv.setUser(user); it works with this line, of course
    privs.add(priv);
    user.setPrivileges(privs);
    //session.save(user);

权限没有绑定用户。 有什么想法吗?

@Entity
@Table(name = "users")

public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private Long id;

@Column(name="email", nullable = false, unique = true)
private String email;

@Column(name="password")
private String password;

@Column(name="user_type")
@Enumerated(EnumType.STRING)
private UserType userType;

@OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY, mappedBy = "user")
private Set<Privilege> privileges = new HashSet<>();

// getters,setters

@Entity
@Table(name = "privileges", uniqueConstraints = @UniqueConstraint(columnNames = {"user_id", "privilege"}))
public class Privilege {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

@Column(name = "privilege")
private String privilege;

@ManyToOne
@JoinColumn(name = "user_id", nullable = false)
private User user;

// getters setters

2 个答案:

答案 0 :(得分:2)

为了确保我的声明&#34;权限没有绑定用户&#34; 。如果取消注释priv.setUser(user),则hibernate能够将用户与数据库中的权限相关联(即,在权限表中正确填充user_id字段)。如果你注释掉这一行,你就不会在权限表中看到user_id被关联。是吗?

如果是这样,原因是,您在oneToMany注释中指定了mappedBy=user。这通知hibernate该关联由权限中的用户字段管理。因此,当hibernate插入权限记录时,它会查看用户字段以填充userID。

使用priv.setUser(user) hibernate现在知道该特权必须与哪个用户相关联,如果你没有设置它,它将为null,你会看到针对user_id列的空值。

或者,如果我误解了这个问题,请告诉我。

答案 1 :(得分:0)

当您的Hibernate保存过程将导致ACTION_SAVE_UPDATE操作,但JPA将传递ACTION_PERSIST和ACTION_MERGE时,它将不匹配并导致级联无法执行。

如果删除JPA级联--javax.persistence.CascadeType,请将其替换为Hibernate cascade - org.hibernate.annotations.Cascade,使用CascadeType.SAVE_UPDATE。

必须有效。