Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.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
Java 使用联接表休眠多对多级联存储_Java_Hibernate - Fatal编程技术网

Java 使用联接表休眠多对多级联存储

Java 使用联接表休眠多对多级联存储,java,hibernate,Java,Hibernate,如果可能的话,这就是我想要实现的目标。 我正在尝试使用级联将以下对象保存到DB中 这是我遇到的问题的一个简化示例。我认为它的工作方式是hibernate应该按顺序插入“User”然后是“Group”然后是“UserGroup”,但实际情况是,它先插入“User”然后是“UserGroup”,这会导致下面日志中的组出现“对象引用未保存的临时实例”错误 显然,用它们自己的save()调用保存单个对象是可行的,但实际的数据库要比这个大得多,我宁愿避免这样做 下面的“TestCode”复制了数据是如何从

如果可能的话,这就是我想要实现的目标。 我正在尝试使用级联将以下对象保存到DB中

这是我遇到的问题的一个简化示例。我认为它的工作方式是hibernate应该按顺序插入“User”然后是“Group”然后是“UserGroup”,但实际情况是,它先插入“User”然后是“UserGroup”,这会导致下面日志中的组出现“对象引用未保存的临时实例”错误

显然,用它们自己的save()调用保存单个对象是可行的,但实际的数据库要比这个大得多,我宁愿避免这样做

下面的“TestCode”复制了数据是如何从JSON数据反序列化的

我怀疑这与我的映射有关,但我无法查明原因

作为参考,我使用Hibernate 5.2.10.Final

那么我错过了什么

User.java

@Entity
@Table(name = "User")
public class User implements java.io.Serializable {

private static final long serialVersionUID = -7899020279254796671L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "userID", unique = true, nullable = false)
private int userId;

@Column(name = "name", nullable = false, length = 45)
private String name;

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL,mappedBy = "id.user")
private Set<UserGroup> userGroups = new HashSet<UserGroup>(0);
//Getters, setters, etc...
}
UserGroupdId.java

@Embeddable
public class UserGroupId implements java.io.Serializable {

private static final long serialVersionUID = -3806643465171954306L;

@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "groupID", nullable = false, insertable = false, updatable = false)
private Group group;

@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "userID", nullable = false, insertable = false, updatable = false)
private User user;
}
测试代码

User u = new User();
u.setName("User");

Group g = new Group();
g.setName("Group");


UserGroup ug = new UserGroup();
UserGroupId id = new UserGroupId();
ug.setId(id);
ug.getId().setGroup(g);
ug.getId().setUser(u);

ug.setDefaultGroup(false);
u.getUserGroups().add(ug);


session.saveOrUpdate(u);
日志条目

[DEBUG] 2017-08-03 10:19:43.497 [main] SQL - insert into M2M.User (name) values (?)
[DEBUG] 2017-08-03 10:19:43.497 [main] SQL - insert into M2M.User (name) values (?)
[TRACE] 2017-08-03 10:19:43.510 [main] BasicBinder - binding parameter [1] as [VARCHAR] - [User]
[TRACE] 2017-08-03 10:19:43.510 [main] BasicBinder - binding parameter [1] as [VARCHAR] - [User]
[DEBUG] 2017-08-03 10:19:43.541 [main] IdentifierGeneratorHelper - Natively generated identity: 65
[DEBUG] 2017-08-03 10:19:43.541 [main] ResourceRegistryStandardImpl - HHH000387: ResultSet's statement was not registered
[DEBUG] 2017-08-03 10:19:43.546 [main] SQL - select usergroup_.groupID, usergroup_.userID, usergroup_.defaultGroup as defaultG1_2_ from M2M.UserGroup usergroup_ where usergroup_.groupID=? and usergroup_.userID=?
[DEBUG] 2017-08-03 10:19:43.546 [main] SQL - select usergroup_.groupID, usergroup_.userID, usergroup_.defaultGroup as defaultG1_2_ from M2M.UserGroup usergroup_ where usergroup_.groupID=? and usergroup_.userID=?
[ERROR] 2017-08-03 10:19:43.546 [main] M2MTest - org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance beforeQuery flushing: m2m.Group

从关联中级联是没有意义的

此外,对多对多关联级联
REMOVE
操作也没有意义,因为两个映射实体都是父实体,而联接表是此关联中的子实体

因此,您有两个选择:

  • 如果要映射,需要分别保存
    用户
    ,并在设置关联双方时级联到
    用户组
  • 您可以跳过对联接表的映射,级联将按预期工作。但是,在映射集合关联时,请确保使用列表而不是
    列表
  • User u = new User();
    u.setName("User");
    
    Group g = new Group();
    g.setName("Group");
    
    
    UserGroup ug = new UserGroup();
    UserGroupId id = new UserGroupId();
    ug.setId(id);
    ug.getId().setGroup(g);
    ug.getId().setUser(u);
    
    ug.setDefaultGroup(false);
    u.getUserGroups().add(ug);
    
    
    session.saveOrUpdate(u);
    
    [DEBUG] 2017-08-03 10:19:43.497 [main] SQL - insert into M2M.User (name) values (?)
    [DEBUG] 2017-08-03 10:19:43.497 [main] SQL - insert into M2M.User (name) values (?)
    [TRACE] 2017-08-03 10:19:43.510 [main] BasicBinder - binding parameter [1] as [VARCHAR] - [User]
    [TRACE] 2017-08-03 10:19:43.510 [main] BasicBinder - binding parameter [1] as [VARCHAR] - [User]
    [DEBUG] 2017-08-03 10:19:43.541 [main] IdentifierGeneratorHelper - Natively generated identity: 65
    [DEBUG] 2017-08-03 10:19:43.541 [main] ResourceRegistryStandardImpl - HHH000387: ResultSet's statement was not registered
    [DEBUG] 2017-08-03 10:19:43.546 [main] SQL - select usergroup_.groupID, usergroup_.userID, usergroup_.defaultGroup as defaultG1_2_ from M2M.UserGroup usergroup_ where usergroup_.groupID=? and usergroup_.userID=?
    [DEBUG] 2017-08-03 10:19:43.546 [main] SQL - select usergroup_.groupID, usergroup_.userID, usergroup_.defaultGroup as defaultG1_2_ from M2M.UserGroup usergroup_ where usergroup_.groupID=? and usergroup_.userID=?
    [ERROR] 2017-08-03 10:19:43.546 [main] M2MTest - org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance beforeQuery flushing: m2m.Group