Suppose you have the following database table:
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;
I have the following JPA object as follows:
@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;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSecondName() {
return secondName;
}
public void setSecondName(String secondName) {
this.secondName = secondName;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public Gender getBirthGender() {
return birthGender;
}
public void setBirthGender(Gender birthGender) {
this.birthGender = birthGender;
}
@Override
public Date getCreationTimestamp() {
return creationTimestamp;
}
@Override
public void setCreationTimestamp(Date creationTimestamp) {
this.creationTimestamp = creationTimestamp;
}
@Override
public User getCreatedBy() {
return createdBy;
}
@Override
public void setCreatedBy(User createdBy) {
this.createdBy = createdBy;
}
}
The problem is matching the attribute createdBywith CREATED_BY. When you deploy it to RedHat Wildfly 8.2.0 Final, it starts in an endless loop (StackOverflow error). How to properly display it so that the relationship can have one on one without a JPA that has gone crazy?
I don't know why this matters, but mine persistence.xmllooks like this:
<?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>
<jta-data-source>java:/jdbc/MyAppXADS</jta-data-source>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="hibernate.hbm2ddl.auto" value="validate" />
<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>