JPA 不维护连接
JPA Not Maintaining Connections
所以看起来一旦程序结束,对象连接就不会保留。让我用一个简单的例子来解释:
//向某人添加朋友并"sending"该朋友发消息。
em.getTransaction().begin();
Friend person = new Friend();
person.setName("One");
Friend friend = new Friend();
friend.settName("Two");
Message messageToFriend = new Message();
messageToFriend.setMessage("Hi");
friend.getMessages().add(messageToFriend);
person.getFriends().add(friend);
em.persist(person);
em.getTransaction().commit();
//测试代码:
Query q = em.createQuery("select f from Friend f where f.name = 'One'");
List<Friend> personList = q.getResultList();
Friend retrievedPerson = personList.get(0);
System.out.println("Friend size: "+retrievedPerson.getFriends().size());
if(retrievedPerson.getFriends().size() > 0){
List<Message> messagesToFriend = retrievedPerson.getFriends().get(0).getMessages();
System.out.println("Friend message size: "+messagesToFriend.size());
if(messagesToFriend.size() > 0){
System.out.println("Message to "+retrievedPerson.getFriends().get(0).getName()+": "+messagesToFriend.get(0).getMessage());
}
}
这将按预期打印:
好友数量:1
好友消息大小:1
给二人留言:嗨
但是一旦程序结束,我再次尝试测试代码:
好友数量:0
如果我查询所有朋友,我得到两个朋友:一和二,但两者之间的联系消失了。甚至 Friend 上的 Message 也不见了(尽管它也在数据库中并且查询 Messages 得到了 Message)。
为什么对象之间的连接会丢失?
我正在使用 MySQL 和 EclipseLink。
附加代码:
@Entity
public class Friend {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
public String id;
private String name;
@OneToMany(mappedBy="parentFriend", cascade = CascadeType.PERSIST)
private List<Friend>friends = new ArrayList<Friend>();
@ManyToOne
private Friend parentFriend;
@OneToMany(mappedBy="friend", cascade = CascadeType.PERSIST)
private List<Message>messages = new ArrayList<Message>();
public List<Message>getMessages(){
return messages;
}
public List<Friend>getFriends(){
return friends;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Entity
public class Message {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private String id;
@ManyToOne
private Friend friend;
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
您可能需要在提交后使用 em.flush()。 JPA 不保证数据实际保存到数据库的时间。我相信 em.flush() 方法会明确保留它,假设您还不想关闭实体管理器。
对不起,再次查看您的问题后,恐怕我的回答有误。我认为问题是因为您的代码没有交叉 link friends 和 parentFriend 字段。您的代码应该更像:
Friend a = new Friend();
Friend b = new Friend();
a.getFriends().add(b);
b.setParentFriend(a);
如果没有设置两个字段,linkage 将不会发生,即使使用持久级联也是如此。
所以看起来一旦程序结束,对象连接就不会保留。让我用一个简单的例子来解释:
//向某人添加朋友并"sending"该朋友发消息。
em.getTransaction().begin();
Friend person = new Friend();
person.setName("One");
Friend friend = new Friend();
friend.settName("Two");
Message messageToFriend = new Message();
messageToFriend.setMessage("Hi");
friend.getMessages().add(messageToFriend);
person.getFriends().add(friend);
em.persist(person);
em.getTransaction().commit();
//测试代码:
Query q = em.createQuery("select f from Friend f where f.name = 'One'");
List<Friend> personList = q.getResultList();
Friend retrievedPerson = personList.get(0);
System.out.println("Friend size: "+retrievedPerson.getFriends().size());
if(retrievedPerson.getFriends().size() > 0){
List<Message> messagesToFriend = retrievedPerson.getFriends().get(0).getMessages();
System.out.println("Friend message size: "+messagesToFriend.size());
if(messagesToFriend.size() > 0){
System.out.println("Message to "+retrievedPerson.getFriends().get(0).getName()+": "+messagesToFriend.get(0).getMessage());
}
}
这将按预期打印:
好友数量:1
好友消息大小:1
给二人留言:嗨
但是一旦程序结束,我再次尝试测试代码:
好友数量:0
如果我查询所有朋友,我得到两个朋友:一和二,但两者之间的联系消失了。甚至 Friend 上的 Message 也不见了(尽管它也在数据库中并且查询 Messages 得到了 Message)。
为什么对象之间的连接会丢失?
我正在使用 MySQL 和 EclipseLink。
附加代码:
@Entity
public class Friend {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
public String id;
private String name;
@OneToMany(mappedBy="parentFriend", cascade = CascadeType.PERSIST)
private List<Friend>friends = new ArrayList<Friend>();
@ManyToOne
private Friend parentFriend;
@OneToMany(mappedBy="friend", cascade = CascadeType.PERSIST)
private List<Message>messages = new ArrayList<Message>();
public List<Message>getMessages(){
return messages;
}
public List<Friend>getFriends(){
return friends;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Entity
public class Message {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private String id;
@ManyToOne
private Friend friend;
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
您可能需要在提交后使用 em.flush()。 JPA 不保证数据实际保存到数据库的时间。我相信 em.flush() 方法会明确保留它,假设您还不想关闭实体管理器。
对不起,再次查看您的问题后,恐怕我的回答有误。我认为问题是因为您的代码没有交叉 link friends 和 parentFriend 字段。您的代码应该更像:
Friend a = new Friend();
Friend b = new Friend();
a.getFriends().add(b);
b.setParentFriend(a);
如果没有设置两个字段,linkage 将不会发生,即使使用持久级联也是如此。