1

我正在尝试创建一个简单的 JPA 2.0 风格的单向映射。对象模型很简单

一个用户可以有一个地址。

@Entity
@Table(name = "USERS")
public class User {

@Id
@SequenceGenerator(name="user_seq",sequenceName = "sequence",allocationSize=1) 
@GeneratedValue (generator="user_seq",strategy=GenerationType.SEQUENCE)
@Column(name="userid")
private Long userId;

@Column(name="emailid")
private String emailId;

@OneToOne(cascade=CascadeType.PERSIST)
@PrimaryKeyJoinColumn
private Address address;

public User() {

}

public Long getUserId() {
    return userId;
}

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


public String getEmailId() {
    return emailId;
}

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


public Address getAddress() {
    return address;
}

public void setAddress(Address address) {
    this.address = address;
}


}

@Entity
@Table(name="address")
public class Address {
@Id
@SequenceGenerator(name="address_seq",sequenceName =               "hibernate_sequence",allocationSize=1) 
@GeneratedValue (generator="address_seq",strategy=GenerationType.SEQUENCE)
private long id;


@Column(name="userid")
private long userId;

@Column(name="address")
private String completeAddress;



public Address() {
    super();
}



public Address (String completeAddress) {
    super();
    this.completeAddress = completeAddress;
}



public long getId() {
    return id;
}

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

public long getUserId() {
    return userId;
}

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

public String getCompleteAddress() {
    return completeAddress;
}

public void setCompleteAddress(String completeAddress) {
    this.completeAddress = completeAddress;
}



}

这就是我试图执行以创建新用户并设置该用户的地址。

EntityManager em = entityManagerFactory.createEntityManager();
 EntityTransaction tx = em.getTransaction();
 try {
     tx.begin();
     User user = new User();
     user.setEmailId("test123");
     Address address = new Address();
     address.setCompleteAddress("some address");
     user.setAddress(address);
     em.persist(user);
     tx.commit();
 } catch (Exception e) {
     em.getTransaction().rollback();
 } finally {
     em.close();
 }

这是我得到的错误 -

[EL Warning]: 2013-02-04 16:00:03.376--UnitOfWork(1827795025)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.0.0.v20091127-r5931): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: insert or update on table "address" violates foreign key constraint "address_userid_fkey"
  Detail: Key (userid)=(0) is not present in table "users".
  Error Code: 0
  Call: INSERT INTO address (ID, userid, address) VALUES (?, ?, ?)
bind => [43, 0, some address]
  Query: InsertObjectQuery(com.jpa.test.Address@5c001eb0)

该错误非常基本,并指出未在地址记录上设置用户 ID 值。似乎这里的持久性管理器有足够的信息来完成这个简单的事务。映射出了什么问题?

4

2 回答 2

1

地址具有您未设置的用户 ID。除非您要设置从地址到用户的一对一关系映射,否则它需要手动设置为用户 ID。使用映射用户标识字段的连接列设置一个onetoone,并标记用户->地址被新关系映射。有关示例,请参见http://www.eclipse.org/eclipselink/api/2.0/javax/persistence/OneToOne.html

于 2013-02-05T01:29:30.583 回答
0

我做错的是定义允许 OneToMany 的关系,但试图将其建模为 OneToOne 关系。

我应该在 User 表上有一个 address_id 列,而不是在地址表上有一个 user_id 。如果我在 User 表上定义 address_id 列并像这样映射我的实体

@OneToOne(cascade=CascadeType.PERSIST)
@JoinColumn(name="address_id")
//@PrimaryKeyJoinColumn
private Address address; 

它工作得很好。这是持久性管理器期望定义的 OneToOne 关系的方式。

于 2013-02-05T11:42:00.123 回答