我一直在努力解决这个问题,似乎无法在任何地方找到解决方案。也许我误解了一些事情,但如果有人能为我清理一些东西,我会非常感激。
我正在尝试在User.class和FacebookProfile.class之间创建OneToOne双向关系。 那就是我希望能够从FacebookProfile实体中查找相应的User实体,反之亦然:
userInstance.getFbprofile();
fbprofileInstance.getUser();
我的 User.class :
@Entity @Access(value=AccessType.FIELD) public class User implements UserDetails { @OneToOne(mappedBy="user") private FacebookProfile fbprofile; }
我的 FacebookProfile.class :
@Entity @Access(value=AccessType.FIELD) public class FacebookProfile { @OneToOne (cascade=CascadeType.ALL) @JoinColumn(name="USER") private User user; }
新的 FacebookProfile 和用户实例在Controller中创建,然后通过服务层发送到持久保存对象的DAO类。
我首先创建并保留新的用户对象。
然后我创建一个新的 FacebookProfile 并将新创建的用户放入其中(setUser)。然后我坚持使用FacebookProfile对象。
用户ID现在存储在FacebookProfile数据库表中,但是没有用户对FacebookProfile的引用,因此以下代码返回 NullPointerException :
User tempUser = userService.findUserById(newUser.getId()); System.out.println("ID "+tempUser.getFbprofile().getId());
以下是控制器中的代码,如果不清楚的话:
//Check if the Facebook user already exist FacebookProfile fbprofile = facebookProfileService.findFacebookProfileById(fbId); User newUser; //Create a new FacebookProfile if it doesn't exist if(fbprofile == null){ //Check if there is a user registered with the facebook email newUser = userService.findUserByEmail(fbEmail); // No User and No FacebookProfile exists if(!newUser.isEnabled()){ newUser = new User(); newUser.setFirstname(fbFirstname); newUser.setLastname(fbLastname); //Set email Email mail = new Email(); mail.setAddress(fbEmail); mail.setName("Facebook"); newUser.addEmail(mail); //Set gender if(fbGender.equalsIgnoreCase("female")){ newUser.setGender(Gender.FEMALE); }else if(fbGender.equalsIgnoreCase("male")) { newUser.setGender(Gender.MALE); } userService.createUser(newUser); } FacebookProfile newProfile = new FacebookProfile(); newProfile.setId(Long.parseLong(fbId)); newProfile.setUsername(fbUsername); newProfile.setFirstname(fbFirstname); newProfile.setLastname(fbLastname); newProfile.setName(fbName); newProfile.setEmail(fbEmail); if(!fbHometown.equals("")){ newProfile.setHometown(fbHometown); newProfile.setHometownID(Long.parseLong(fbHometownID)); } if(!fbLocation.equals("")){ newProfile.setLocation(fbLocation); newProfile.setLocationID(Long.parseLong(fbLocationID)); } newProfile.setLink(fbLink); if(fbGender.equalsIgnoreCase("male")){ newProfile.setGender(Gender.MALE); }else if (fbGender.equalsIgnoreCase("female")) { newProfile.setGender(Gender.FEMALE); } newProfile.setUser(newUser); this.facebookProfileService.createNewFacebookProfile(newProfile); //newUser.setFbprofile(newProfile); }else { //There already exists a FacebookProfile newUser = fbprofile.getUser(); }
我觉得我已经尝试了所有可能的解决方案并且没有让它发挥作用。 我怀疑在之前的一次尝试中, fbprofile 引用是在用户对象中设置的,但从未保留,因为它是在用户对象被持久化了。我使用 JPA2 和 EclipseLink 。
如果某人有解决方案,我们将不胜感激。
答案 0 :(得分:2)
JPA不维持双向关系。 JPA设计者认为维持双向关系会导致死锁,不一致...... Toplink在JPA之前支持双向关系。我使用Toplink多年,我确实遇到了与双向关系有关的一些不一致。你应该手动维护双向关系。比如;
newProfile.setUser(newUser);
newUser.setFbProfile(newProfile);
编辑:
好吧,你想让我详细说明我的答案..你应该改变你的代码,这些代码会持久存在FbProfile实体,如;
newProfile.setUser(newUser);
newUser.setFbprofile(newProfile);
this.facebookProfileService.createNewFacebookProfile(newProfile);
作为替代方案,您还可以更改FbProfile setUser方法;
public void setUser(User aUser) {
if (this.user==aUser)
return;
if (this.user != null) {
this.user.setFbProfile(null);
}
this.user = aUser;
if (this.user!=null) {
this.user.setFbprofile(this);
}
}