Code Bye

hibetnate 中 one-to-many问题

本人新手,在做整合时,各种问题不停………..求大哥..
user 和 subject是one-to-many的双向关系,
但在保存subject时,出现
Exception in thread “main” org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: cc.struts.domain.User; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: cc.struts.domain.User
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:648)
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:424)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.persist(HibernateTemplate.java:804)
at cc.service.test.UserAndSubjectTest.main(UserAndSubjectTest.java:29)
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: cc.struts.domain.User
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:102)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:637)
        ……………………………

应该是id什么错误了,可我不知道错在那,我用的是mySql,
下面是用到的表

@Entity
public class User {
private Date birthday;
private String email;
private int id;
private String passWorld;
private String phone;
private String userName;
private List<Subject> subjects;

@OneToMany(mappedBy=”user”,targetEntity=Subject.class,cascade=CascadeType.ALL)
public List<Subject> getSubjects() {
return subjects;
}
public void setSubjects(List<Subject> subjects) {
this.subjects = subjects;
}
/*主键*/
@Id
@GeneratedValue
public int getId() {
return id;
}
public String getPassWorld() {
return passWorld;
}
public String getPhone() {
return phone;
}
public String getUserName() {
return userName;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public void setEmail(String email) {
this.email = email;
}
public void setId(int id) {
this.id = id;
}
//…其它getXxx,setXxx.
}

@Entity
public class Subject {
private int id;
private String title;
private Date time;
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
private User user;

@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@ManyToOne(cascade=CascadeType.ALL)
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
//…其它getXxx,setXxx.
}

//发表主题的form
<c:form action=”user_publishSubject” namespace=”/user” name=”publishSubject”>
<c:textfield name=”subject.title” label=”主题标题” />
<br />
<c:textarea name=”subject.content” label=”主题内容” />
<br/>
<c:submit value=”发表主题” />
</c:form>

//UserAction方法
/* 发表主题 */
public String publishSubject() {
if (subject != null) {
User user = (User) context.getSession().get(“user”);
if (user == null) {
message = “请登陆!”;
return “login”;
}
boolean b = userServiceImpl.publishSubject(subject, user);
if(b ==true){
message =”发表成功!”;
return “showUser”;
}
}
message=”发表失败!”;
return “showUser”;
}

   //userDaoimpl中的方法
/*发表主题*/
@Override
public boolean publishSubject(Subject subject,User user) {
try {
                      //设置关联
subject.setUser(user);
                        //保存subject
hibernateTemplate.persist(subject);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}


10分
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = “USER_ID”, nullable = false)
public User getUser() {
return user;
}

30分
暂不说你这样做的一个极大的危险在哪里。
本着先解决问题的原则,我说一下错误的可能性:
subject.setUser(user);
hibernateTemplate.persist(subject);

从代码来看,subject与user有关系,但反之则没有,恰恰你把User设为了主控端,所以框架提示“detached entity”错误。也就是说需要在user里能添加subject对象才行,在User.java代码里加上:

//User.java
public void addSubject(Subject subject){
    if(this.subjects == null){
        this.subjects = new ArrayList<Subject>(1);
    }
    subject.setUser(this);
    this.subjects.add(subject);
}

//UserDaoimpl.java
user.addSubject(subject);
hibernateTemplate.persist(subject);

至于这套方案中极大的危险或不合理性在哪里,用了后就会知道。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明hibetnate 中 one-to-many问题