Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA:与确切类型实体的一对一关系_Java_Jpa_Jpa 2.0 - Fatal编程技术网

Java JPA:与确切类型实体的一对一关系

Java JPA:与确切类型实体的一对一关系,java,jpa,jpa-2.0,Java,Jpa,Jpa 2.0,假设您有以下数据库表: CREATE TABLE IF NOT EXISTS USER ( USER_NAME VARCHAR(20) NOT NULL, FIRST_NAME VARCHAR(50) NOT NULL, SECOND_NAME VARCHAR(50) NOT NULL DEFAULT '', SURNAME VARCHAR(50) NOT

假设您有以下数据库表:

CREATE TABLE IF NOT EXISTS USER (
    USER_NAME               VARCHAR(20) NOT NULL,
    FIRST_NAME              VARCHAR(50) NOT NULL,
    SECOND_NAME             VARCHAR(50) NOT NULL DEFAULT '',
    SURNAME                 VARCHAR(50) NOT NULL,
    BIRTH_DATE              DATE NOT NULL,
    BIRTH_GENDER            ENUM ('M', 'F') NOT NULL,
    CREATION_TIMESTAMP      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CREATED_BY              VARCHAR(20) NOT NULL,
    LAST_UPDATE_TIMESTAMP   TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP,
    LAST_UPDATED_BY         VARCHAR(20),
    DELETION_TIMESTAMP      TIMESTAMP NULL,
    DELETED_BY              VARCHAR(20),

    PRIMARY KEY (USER_NAME),
    FOREIGN KEY (CREATED_BY) REFERENCES USER(USER_NAME),
    FOREIGN KEY (LAST_UPDATED_BY) REFERENCES USER(USER_NAME),
    FOREIGN KEY (DELETED_BY) REFERENCES USER(USER_NAME)
) CHARACTER SET utf8;
我拥有以下JPA实体,如下所示:

/**
 * @author Buhake Sindi
 *
 */
@Entity
@Table(name="USER")
@Access(AccessType.FIELD)
public class User implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1600376007707987934L;

    @Id
    @Column(name="USER_NAME", nullable=false)
    private String id;

    @Column(name="FIRST_NAME", nullable=false)
    private String firstName;

    @Column(name="SECOND_NAME", nullable=false)
    private String secondName;

    @Column(name="SURNAME", nullable=false)
    private String surname;

    @Temporal(TemporalType.DATE)
    @Column(name="BIRTH_DATE", nullable=false)
    private Date birthDate;

    @Column(name="BIRTH_GENDER", columnDefinition="ENUM('M', 'F')", nullable=false)
    @Enumerated(EnumType.STRING)
    private Gender birthGender;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="CREATION_TIMESTAMP", insertable=false, updatable=false, nullable=false)
    private Date creationTimestamp;

    @OneToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="CREATED_BY", insertable=true, updatable=false, nullable=false)
    private User createdBy;

    /* (non-Javadoc)
     * @see za.co.sindi.entity.IDBasedEntity#getId()
     */
    public String getId() {
        // TODO Auto-generated method stub
        return id;
    }

    /* (non-Javadoc)
     * @see za.co.sindi.entity.IDBasedEntity#setId(java.io.Serializable)
     */
    public void setId(String id) {
        // TODO Auto-generated method stub
        this.id = id;
    }

    /**
     * @return the firstName
     */
    public String getFirstName() {
        return firstName;
    }

    /**
     * @param firstName the firstName to set
     */
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    /**
     * @return the secondName
     */
    public String getSecondName() {
        return secondName;
    }

    /**
     * @param secondName the secondName to set
     */
    public void setSecondName(String secondName) {
        this.secondName = secondName;
    }

    /**
     * @return the surname
     */
    public String getSurname() {
        return surname;
    }

    /**
     * @param surname the surname to set
     */
    public void setSurname(String surname) {
        this.surname = surname;
    }

    /**
     * @return the birthDate
     */
    public Date getBirthDate() {
        return birthDate;
    }

    /**
     * @param birthDate the birthDate to set
     */
    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    /**
     * @return the birthGender
     */
    public Gender getBirthGender() {
        return birthGender;
    }

    /**
     * @param birthGender the birthGender to set
     */
    public void setBirthGender(Gender birthGender) {
        this.birthGender = birthGender;
    }


    /* (non-Javadoc)
     * @see za.co.sindi.entity.AbstractIdentifiableAuditableEntity#getCreationTimestamp()
 */
    @Override
    public Date getCreationTimestamp() {
    // TODO Auto-generated method stub
    return creationTimestamp;
}

/* (non-Javadoc)
 * @see za.co.sindi.entity.AbstractIdentifiableAuditableEntity#setCreationTimestamp(java.util.Date)
 */
@Override
public void setCreationTimestamp(Date creationTimestamp) {
    // TODO Auto-generated method stub
    this.creationTimestamp = creationTimestamp;
}

/* (non-Javadoc)
 * @see za.co.sindi.entity.AbstractIdentifiableAuditableEntity#getCreatedBy()
 */
@Override
public User getCreatedBy() {
    // TODO Auto-generated method stub
    return createdBy;
}

/* (non-Javadoc)
 * @see za.co.sindi.entity.AbstractIdentifiableAuditableEntity#setCreatedBy(java.lang.Object)
 */
    @Override
    public void setCreatedBy(User createdBy) {
        // TODO Auto-generated method stub
        this.createdBy = createdBy;
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="myapp-persistence-unit" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider><!-- used since Hibernate 4.3.x instead of org.hibernate.ejb.HibernatePersistence -->
        <jta-data-source>java:/jdbc/MyAppXADS</jta-data-source>
        <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode><!-- This is the default anyway. -->
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="validate" /><!-- DBA's are paid to create DB tables so never do update | create | create-drop. -->
            <property name="hibernate.cache.use_second_level_cache" value="true" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.enable_lazy_load_no_trans" value="true"/>
        </properties>
    </persistence-unit> 
</persistence>
问题在于将属性
createdBy
映射到
createdBy
列时。将其部署到RedHat Wildfly 8.2.0 Final时,它会运行到一个无限循环(StackOverflow错误)。我如何正确地映射它,使关系可以是一对一的,而不会让JPA发疯


我不知道为什么这是相关的,但我的
persistence.xml
如下所示:

/**
 * @author Buhake Sindi
 *
 */
@Entity
@Table(name="USER")
@Access(AccessType.FIELD)
public class User implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1600376007707987934L;

    @Id
    @Column(name="USER_NAME", nullable=false)
    private String id;

    @Column(name="FIRST_NAME", nullable=false)
    private String firstName;

    @Column(name="SECOND_NAME", nullable=false)
    private String secondName;

    @Column(name="SURNAME", nullable=false)
    private String surname;

    @Temporal(TemporalType.DATE)
    @Column(name="BIRTH_DATE", nullable=false)
    private Date birthDate;

    @Column(name="BIRTH_GENDER", columnDefinition="ENUM('M', 'F')", nullable=false)
    @Enumerated(EnumType.STRING)
    private Gender birthGender;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="CREATION_TIMESTAMP", insertable=false, updatable=false, nullable=false)
    private Date creationTimestamp;

    @OneToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="CREATED_BY", insertable=true, updatable=false, nullable=false)
    private User createdBy;

    /* (non-Javadoc)
     * @see za.co.sindi.entity.IDBasedEntity#getId()
     */
    public String getId() {
        // TODO Auto-generated method stub
        return id;
    }

    /* (non-Javadoc)
     * @see za.co.sindi.entity.IDBasedEntity#setId(java.io.Serializable)
     */
    public void setId(String id) {
        // TODO Auto-generated method stub
        this.id = id;
    }

    /**
     * @return the firstName
     */
    public String getFirstName() {
        return firstName;
    }

    /**
     * @param firstName the firstName to set
     */
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    /**
     * @return the secondName
     */
    public String getSecondName() {
        return secondName;
    }

    /**
     * @param secondName the secondName to set
     */
    public void setSecondName(String secondName) {
        this.secondName = secondName;
    }

    /**
     * @return the surname
     */
    public String getSurname() {
        return surname;
    }

    /**
     * @param surname the surname to set
     */
    public void setSurname(String surname) {
        this.surname = surname;
    }

    /**
     * @return the birthDate
     */
    public Date getBirthDate() {
        return birthDate;
    }

    /**
     * @param birthDate the birthDate to set
     */
    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    /**
     * @return the birthGender
     */
    public Gender getBirthGender() {
        return birthGender;
    }

    /**
     * @param birthGender the birthGender to set
     */
    public void setBirthGender(Gender birthGender) {
        this.birthGender = birthGender;
    }


    /* (non-Javadoc)
     * @see za.co.sindi.entity.AbstractIdentifiableAuditableEntity#getCreationTimestamp()
 */
    @Override
    public Date getCreationTimestamp() {
    // TODO Auto-generated method stub
    return creationTimestamp;
}

/* (non-Javadoc)
 * @see za.co.sindi.entity.AbstractIdentifiableAuditableEntity#setCreationTimestamp(java.util.Date)
 */
@Override
public void setCreationTimestamp(Date creationTimestamp) {
    // TODO Auto-generated method stub
    this.creationTimestamp = creationTimestamp;
}

/* (non-Javadoc)
 * @see za.co.sindi.entity.AbstractIdentifiableAuditableEntity#getCreatedBy()
 */
@Override
public User getCreatedBy() {
    // TODO Auto-generated method stub
    return createdBy;
}

/* (non-Javadoc)
 * @see za.co.sindi.entity.AbstractIdentifiableAuditableEntity#setCreatedBy(java.lang.Object)
 */
    @Override
    public void setCreatedBy(User createdBy) {
        // TODO Auto-generated method stub
        this.createdBy = createdBy;
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="myapp-persistence-unit" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider><!-- used since Hibernate 4.3.x instead of org.hibernate.ejb.HibernatePersistence -->
        <jta-data-source>java:/jdbc/MyAppXADS</jta-data-source>
        <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode><!-- This is the default anyway. -->
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="validate" /><!-- DBA's are paid to create DB tables so never do update | create | create-drop. -->
            <property name="hibernate.cache.use_second_level_cache" value="true" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.enable_lazy_load_no_trans" value="true"/>
        </properties>
    </persistence-unit> 
</persistence>

org.hibernate.jpa.HibernatePersistenceProvider
java:/jdbc/MyAppXADS
启用\u选择性

映射看起来很好,因此我假设这一定是导致问题的实际数据库状态

您声明由创建的
非空
;那么,如何在空的
user
表中插入第一个用户呢?解决这个问题的唯一方法是指出第一个用户实际上是自己创建的

如果是这样的话(或者你有自引用用户出于任何其他原因,例如,如果你保存的用户是注册自己的,并且不是由其他用户创建的),那么无限递归的可能性很大。例如,检查您的
toString
equals
hashCode
(我在您发布的
User
类中没有看到它们,可能您为了简洁而省略了它们)

我希望Hibernate能够处理这种情况,但它可能会尝试在同一个
用户
实例中反复解析
createdBy
关联

不管是什么原因,错误的堆栈跟踪应该给出无限递归起源的提示


此外,您可能希望为
org.hibernate
包启用
跟踪
日志级别,以查看到底发生了什么。

此问题的实际问题是
用户
实体是
@MappedSuperclass
AbstractSoftDeleteAuditableEntity
的子类(它是泛型的)。在
MappedSuperclass
实体中,将
createdBy
lastedby
deletedBy
属性分配给绑定类型
User
。在部署应用程序时,Hibernate循环尝试验证
用户
实体,并导致出现
堆栈溢出错误
。我将
用户
实体设置为一个简单的实体,现在所有实体都已部署并验证,没有错误。

您可以添加您的持久性吗。xmlI正在使用JPA 2.1持久性框架,为什么需要我的
持久性.xml
?我使用了您的sql和实体定义,它工作正常,我想查看配置,只是在我的环境中进行模拟看看我更新的帖子。我没有发现任何问题,我投了赞成票,我希望另一个开发人员能帮助
解决这个问题的唯一方法是指出第一个用户实际上是自己创建的。
。答对 了这是你创造自我的唯一途径。我将发布发生的实际问题以及我是如何解决的。