JPA一对一关系

时间:2013-04-08 06:35:09

标签: jpa entitymanager

我的User.java JPA代码

public class User implements java.io.Serializable {

    private String mobile;
    private String emailId;
    private String userName;
    private String password;

    private Student student = new Student();    
    private Staff staff = new Staff();

    public User() {
    }

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "user_id", nullable = false)
    public Long getUserId() {
        return this.userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    @Column(name = "mobile", nullable = false)
    public String getMobile() {
        return this.mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    @Column(name = "email_id", unique = true, nullable = false, length = 80)
    public String getEmailId() {
        return this.emailId;
    }

    public void setEmailId(String emailId) {
        this.emailId = emailId;
    }

    @Column(name = "user_name", unique = true, nullable = false, length = 45)
    public String getUserName() {
        return this.userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Column(name = "password", nullable = false, length = 45)
    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @OneToOne(mappedBy = "studentUser", fetch = FetchType.LAZY)
    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    @OneToOne(mappedBy = "staffUser", fetch = FetchType.LAZY)
    public Staff getStaff() {
        return staff;
    }

    public void setStaff(Staff staff) {
        this.staff = staff;
    }

}

我的Student.java JPA代码

public class Student implements java.io.Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;
    private User studentUser;
    private String classRollNumber;
    private Timestamp admissionDate;

    public Student() {
    }

    public Student(User studentUser, String classRollNumber, Timestamp admissionDate) {
        this.studentUser = studentUser;
        this.classRollNumber = classRollNumber;
        this.admissionDate = admissionDate;
    }

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id", nullable = false)
    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    public User getStudentUser() {
        return this.studentUser;
    }

    public void setStudentUser(User studentUser) {
        this.studentUser = studentUser;
    }

    @Column(name = "class_roll_number", nullable = false, length = 55)
    public String getClassRollNumber() {
        return this.classRollNumber;
    }

    public void setClassRollNumber(String classRollNumber) {
        this.classRollNumber = classRollNumber;
    }

    @Column(name = "admission_date", nullable = false, length = 19)
    public Timestamp getAdmissionDate() {
        return this.admissionDate;
    }

    public void setAdmissionDate(Timestamp admissionDate) {
        this.admissionDate = admissionDate;
    }
}

我的Staff.java JPA代码

public class Staff implements java.io.Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;
    private User staffUser;
    private String staffNumber;
    private Timestamp joiningDate;

    public Staff() {
    }

    public Staff(User staffUser, String staffNumber, Timestamp joiningDate) {
        this.staffUser = staffUser;
        this.staffNumber = staffNumber;
        this.joiningDate = joiningDate;
    }

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id", nullable = false)
    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    public User getStaffUser() {
        return staffUser;
    }

    public void setStaffUser(User staffUser) {
        this.staffUser = staffUser;
    }

    @Column(name = "staff_number", nullable = false, length = 55)
    public String getStaffNumber() {
        return this.staffNumber;
    }

    public void setStaffNumber(String staffNumber) {
        this.staffNumber = staffNumber;
    }

    @Column(name = "joining_date", nullable = false, length = 19)
    public Timestamp getJoiningDate() {
        return this.joiningDate;
    }

    public void setJoiningDate(Timestamp joiningDate) {
        this.joiningDate = joiningDate;
    }
}

我的持久性逻辑

public void createUser(){
    User user = new User();
    user.setEmailId("test");
    user.setUserName("test");
    user.setPassword("test");
    user.setMobile("test");
    saveEntity(user);        
}

public void saveEntity(Object object){
    getEntityManager().getTransaction().begin();        
    getEntityManager().persist(object);     
    getEntityManager().getTransaction().commit();

}

public static void main(String ar[]){
    UserDaoImpl daoImpl = new UserDaoImpl();
    daoImpl.createUser();
}

当我尝试坚持实体以下错误发生时,请建议可能的解决方案。 错误堆栈跟踪:

8 Apr, 2013 11:44:05 AM org.hibernate.annotations.common.Version <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.1.Final}
8 Apr, 2013 11:44:05 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.1.7.Final}
8 Apr, 2013 11:44:05 AM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
8 Apr, 2013 11:44:05 AM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
8 Apr, 2013 11:44:05 AM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)
8 Apr, 2013 11:44:05 AM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20
8 Apr, 2013 11:44:05 AM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000006: Autocommit mode: true
8 Apr, 2013 11:44:05 AM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/jpatest]
8 Apr, 2013 11:44:05 AM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000046: Connection properties: {user=root, password=****, autocommit=true, release_mode=auto}
8 Apr, 2013 11:44:05 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
8 Apr, 2013 11:44:05 AM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory
8 Apr, 2013 11:44:05 AM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Hibernate: insert into jpatest.tblmuser (email_id, manager_id, mobile, password, user_name) values (?, ?, ?, ?, ?)
Exception in thread "main" javax.persistence.RollbackException: Error while committing the transaction
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:92)
    at org.javalab.bl.dao.BaseDaoImpl.saveEntity(BaseDaoImpl.java:27)
    at org.javalab.bl.dao.UserDaoImpl.createUser(UserDaoImpl.java:15)
    at org.javalab.bl.dao.UserDaoImpl.main(UserDaoImpl.java:39)
Caused by: java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing: org.javalab.bl.entity.User.staff -> org.javalab.bl.entity.Staff
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1374)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:80)
    ... 3 more
Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing: org.javalab.bl.entity.User.staff -> org.javalab.bl.entity.Staff
    at org.hibernate.engine.spi.CascadingAction$8.noCascade(CascadingAction.java:380)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:176)
    at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:160)
    at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:151)
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1210)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:399)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:75)
    ... 3 more

提前致谢 vivek shah

1 个答案:

答案 0 :(得分:2)

您的用户实体会在实例时自动创建关联人员。

 private Staff staff = new Staff();

因此,当您保留用户时,此用户会引用未保存的工作人员实例,并且没有定义级联(级联在工作人员端)。

你有3种方法可以修复它:

  • 删除private Staff staff = new Staff();实体中的默认实例User
  • User实体中的员工OneToOne重新关联中添加级联。
  • 在持久保存用户之前,手动保留相关人员。