hibernate @onetomany 双向映射不能正确映射数据
hibernate @onetomany bidirectinal mapping doesn't map data correctly
我有两个实体 classes.User 和 FriendStatus.Friend 状态保存来自其他用户的好友请求的数据。
用户:
@Entity
@Table(name = "USERS")
@XmlRootElement
public class User implements Serializable {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "acceptor")
@LazyCollection(LazyCollectionOption.FALSE)
private List<Message> acceptedMessages;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "sender")
@LazyCollection(LazyCollectionOption.FALSE)
private List<Message> sentMessages;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
@Column(name = "phone_number")
private String phoneNumber;
@OneToMany(cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
private List<User> friends;
@OneToMany(cascade = CascadeType.ALL,mappedBy="requestAcceptor")
@LazyCollection(LazyCollectionOption.FALSE)
@JsonIgnoreProperties("requestAcceptor")
private List<FriendStatus> acceptedFriendRequests;
@OneToMany(cascade = CascadeType.ALL,mappedBy = "requestSender")
@LazyCollection(LazyCollectionOption.FALSE)
@JsonIgnoreProperties("requestSender")
private List<FriendStatus> sentFriendRequests;
@Column(name = "profile_status")
private String profileStatus;
@Enumerated(EnumType.STRING)
@Column(name = "activation_status")
private UserActivationStatus activationStatus;
好友状态:
@Entity
@Table(name="FRIEND_STATUS")
public class FriendStatus implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long Id;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="request_sender_id")
@JsonIgnoreProperties("sentFriendRequests")
private User requestSender;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="request_acceptor_id")
@JsonIgnoreProperties("acceptedFriendRequests")
private User requestAcceptor;
@Enumerated(EnumType.STRING)
@Column(name = "request_status")
private FriendRequestStatus friendRequestStatus;
当我第一次将 FriendStatus 对象保存到数据库时,它工作 fine.But 当我第二次使用相同的 requestAcceptor 对象保存对象时,hibernate 从 request_acceptor_id 列中删除以前的 id 并将其写入新 row.HELP 请我。
编辑:
这是我将对象保存到数据库的方法。
public T create(T object) {
T objectFromDB = object;
Session session = NewHibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = (Transaction) session.beginTransaction();
session.save(object);
transaction.commit();
} catch (HibernateException e) {
if (session != null){
session.getTransaction().rollback();
}
e.printStackTrace();
} finally {
session.close();
}
return objectFromDB;
}
这是我调用创建方法的方法:
public void sendFriendRequest(FriendStatus object) {
FriendStatus status = fDao.create(object);//fDao is the object from Dao class which includes create method.
}
这是我的控制器:
@RequestMapping(value="/sendFriendRequest",method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON,produces = MediaType.APPLICATION_JSON)
public String sendFriendRequest(@RequestBody FriendStatus status) {
serviceUser.sendFriendRequest(status);//serviceUser is the object from class that includes sendFriendRequest method.
return "OK";
}
这是我在数据库中的 table:
+====+================+=====================+===================+
| id | request_status | request_acceptor_id | request_sender_id |
+====+================+=====================+===================+
| 18 | WAITING | NULL | 29 |
+----+----------------+---------------------+-------------------+
| 19 | WAITING | 23 | 30 |
+----+----------------+---------------------+-------------------+
当我使用 id 为 29 的 requestSender 和 id 为 23 的 requestAcceptor 对象保存 FriendStatus 对象(它来自客户端)时,hibernate 将其保存到 id 为 18.After 的列,当我保存第二个 FriendStatus 对象时使用 id 为 30 的 requestSender 和 id 为 23 的 requestAcceptor 对象,hibernate 将 request_acceptor_id 替换为 id 为 18 的行中的 NULL,然后在 db 中创建新行,其中 request_acceptor_id 为 23.But我希望当我添加第二个对象时,第一个对象不 change.I 当我创建具有相同 request_acceptor_id.[=16= 的新列时,不想用 NULL 替换 request_acceptor_id ]
跟你的级联设置有关,
尝试使用以下方式保存:
public void sendFriendRequest(FriendStatus status) {
User requester=userDao.findOne(status.getRequestAcceptor.getId());
User sender=userDao.findOne(status.getRequestSender.getId());
......
statusDao.create(status);
status.getRequestAcceptor(requester);
status.getRequestSender(sender);
statusDao.update(status);
}
status携带的用户有private List sentFriendRequests和private List acceptedFriendRequests;设置为空列表
如果你的事务在整个函数之外,效果会更好,那么你可以使用:
sender.getSentFriendRequests().add(状态) 和 reqester.getacceptedFriendRequests().add(状态);我猜这是@OneToMany 的重点,Cascade.All
否则你可以从集合中删除级联规则
我有两个实体 classes.User 和 FriendStatus.Friend 状态保存来自其他用户的好友请求的数据。
用户:
@Entity
@Table(name = "USERS")
@XmlRootElement
public class User implements Serializable {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "acceptor")
@LazyCollection(LazyCollectionOption.FALSE)
private List<Message> acceptedMessages;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "sender")
@LazyCollection(LazyCollectionOption.FALSE)
private List<Message> sentMessages;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
@Column(name = "phone_number")
private String phoneNumber;
@OneToMany(cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
private List<User> friends;
@OneToMany(cascade = CascadeType.ALL,mappedBy="requestAcceptor")
@LazyCollection(LazyCollectionOption.FALSE)
@JsonIgnoreProperties("requestAcceptor")
private List<FriendStatus> acceptedFriendRequests;
@OneToMany(cascade = CascadeType.ALL,mappedBy = "requestSender")
@LazyCollection(LazyCollectionOption.FALSE)
@JsonIgnoreProperties("requestSender")
private List<FriendStatus> sentFriendRequests;
@Column(name = "profile_status")
private String profileStatus;
@Enumerated(EnumType.STRING)
@Column(name = "activation_status")
private UserActivationStatus activationStatus;
好友状态:
@Entity
@Table(name="FRIEND_STATUS")
public class FriendStatus implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long Id;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="request_sender_id")
@JsonIgnoreProperties("sentFriendRequests")
private User requestSender;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="request_acceptor_id")
@JsonIgnoreProperties("acceptedFriendRequests")
private User requestAcceptor;
@Enumerated(EnumType.STRING)
@Column(name = "request_status")
private FriendRequestStatus friendRequestStatus;
当我第一次将 FriendStatus 对象保存到数据库时,它工作 fine.But 当我第二次使用相同的 requestAcceptor 对象保存对象时,hibernate 从 request_acceptor_id 列中删除以前的 id 并将其写入新 row.HELP 请我。
编辑:
这是我将对象保存到数据库的方法。
public T create(T object) {
T objectFromDB = object;
Session session = NewHibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = (Transaction) session.beginTransaction();
session.save(object);
transaction.commit();
} catch (HibernateException e) {
if (session != null){
session.getTransaction().rollback();
}
e.printStackTrace();
} finally {
session.close();
}
return objectFromDB;
}
这是我调用创建方法的方法:
public void sendFriendRequest(FriendStatus object) {
FriendStatus status = fDao.create(object);//fDao is the object from Dao class which includes create method.
}
这是我的控制器:
@RequestMapping(value="/sendFriendRequest",method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON,produces = MediaType.APPLICATION_JSON)
public String sendFriendRequest(@RequestBody FriendStatus status) {
serviceUser.sendFriendRequest(status);//serviceUser is the object from class that includes sendFriendRequest method.
return "OK";
}
这是我在数据库中的 table:
+====+================+=====================+===================+
| id | request_status | request_acceptor_id | request_sender_id |
+====+================+=====================+===================+
| 18 | WAITING | NULL | 29 |
+----+----------------+---------------------+-------------------+
| 19 | WAITING | 23 | 30 |
+----+----------------+---------------------+-------------------+
当我使用 id 为 29 的 requestSender 和 id 为 23 的 requestAcceptor 对象保存 FriendStatus 对象(它来自客户端)时,hibernate 将其保存到 id 为 18.After 的列,当我保存第二个 FriendStatus 对象时使用 id 为 30 的 requestSender 和 id 为 23 的 requestAcceptor 对象,hibernate 将 request_acceptor_id 替换为 id 为 18 的行中的 NULL,然后在 db 中创建新行,其中 request_acceptor_id 为 23.But我希望当我添加第二个对象时,第一个对象不 change.I 当我创建具有相同 request_acceptor_id.[=16= 的新列时,不想用 NULL 替换 request_acceptor_id ]
跟你的级联设置有关,
尝试使用以下方式保存:
public void sendFriendRequest(FriendStatus status) {
User requester=userDao.findOne(status.getRequestAcceptor.getId());
User sender=userDao.findOne(status.getRequestSender.getId());
......
statusDao.create(status);
status.getRequestAcceptor(requester);
status.getRequestSender(sender);
statusDao.update(status);
}
status携带的用户有private List sentFriendRequests和private List acceptedFriendRequests;设置为空列表
如果你的事务在整个函数之外,效果会更好,那么你可以使用: sender.getSentFriendRequests().add(状态) 和 reqester.getacceptedFriendRequests().add(状态);我猜这是@OneToMany 的重点,Cascade.All
否则你可以从集合中删除级联规则