1

単純なJPA2.0スタイルの単方向マッピングを作成しようとしています。オブジェクトモデルは単純です

1人のユーザーが1つのアドレスを持つことができます。

@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があります。アドレスからユーザーへの1対1の関係マッピングを設定する場合を除いて、手動でユーザーのIDに設定する必要があります。ユーザーIDフィールドをマッピングする結合列を使用してonetooneを設定し、user->addressが新しいリレーションによってマッピングされたことをマークします。例については、 http://www.eclipse.org/eclipselink/api/2.0/javax/persistence/OneToOne.htmlを参照してください。

于 2013-02-05T01:29:30.583 に答える
0

私が間違っていたのは、OneToManyを許可する関係を定義することでしたが、それをOneToOne関係としてモデル化しようとしました。

アドレステーブルにuser_idではなく、Userテーブルにaddress_id列が必要です。Userテーブルにaddress_id列を定義し、エンティティを次のようにマップすると、

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

それはうまく機能します。これは、永続性マネージャが定義されたOneToOne関係を期待する方法です。

于 2013-02-05T11:42:00.123 に答える