エンティティエラーのマッピングの別の繰り返し列


110

他のすべての投稿にもかかわらず、MacOSX、NetBeans 7.2ではGlassFishでこのエラーの解決策を見つけることができません。

Here the error :
SEVERE: Exception while invoking class org.glassfish.persistence.jpa.JPADeployer
prepare method
SEVERE: Exception while preparing the app
SEVERE: [PersistenceUnit: supmarket] Unable to build EntityManagerFactory

...

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity:
com.supmarket.entity.Sale column: customerId
(should be mapped with insert="false" update="false")

ここにコード:

Sale.java

@Entity
public class Sale {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(nullable=false)
    private Long idFromAgency;

    private float amountSold;

    private String agency;

    @Temporal(javax.persistence.TemporalType.DATE)
    private Date createdate;

    @Column(nullable=false)
    private Long productId;

    @Column(nullable=false)
    private Long customerId;

    @ManyToOne(optional=false)
    @JoinColumn(name="productId",referencedColumnName="id_product")
    private Product product;

    @ManyToOne(optional=false)
    @JoinColumn(name="customerId",referencedColumnName="id_customer")
    private Customer customer;


    public void Sale(){}    
    public void Sale(Long idFromAgency, float amountSold, String agency
            , Date createDate, Long productId, Long customerId){        
        ...
    }

    // then getters/setters
}

Customer.java

@Entity
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id_customer")
    private Long id_customer;

    @Column(nullable=false)
    private Long idFromAgency;

    private String  gender,
                    maritalState,
                    firstname,
                    lastname,
                    incomeLevel;

    @OneToMany(mappedBy="customer",targetEntity=Sale.class, fetch=FetchType.EAGER)
    private Collection sales;


    public void Customer(){}

    public void Customer(Long idFromAgency, String gender, String maritalState,
            String firstname, String lastname, String incomeLevel) {
        ...
    }

}

Product.java

public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id_product")
    private Long id_product;

    @Column(nullable=false)
    private Long idFromAgency;

    private String name;

    @OneToMany(mappedBy="product",targetEntity=Sale.class, fetch=FetchType.EAGER)
    private Collection sales;

    //constructors + getters +setters
}

回答:


129

メッセージは明確です。マッピングに列が繰り返されています。つまり、同じデータベース列を2回マップしました。そして確かに、あなたは持っています:

@Column(nullable=false)
private Long customerId;

そしてまた:

@ManyToOne(optional=false)
@JoinColumn(name="customerId",referencedColumnName="id_customer")
private Customer customer;

(同じことがproductId/にも言えproductます)。

他のエンティティをIDで参照するのではなく、エンティティを直接参照する必要があります。customerIdフィールドを削除してください、それは役に立たないです。についても同じようにしproductIdます。販売のお客様IDが必要な場合は、次のようにするだけです。

sale.getCustomer().getId()

1
同じエラーが表示されますが、状況は少し異なります。私のエンティティは、同じタイプの1つ以上のエンティティの父親になることができます。子供たちは父親のIDと自分の一意のIDを参照します。このような循環依存関係を解決するにはどうすればよいですか?
Ciri

@JBNizet 特定のセールを保存するにはどうすればよいcustomerIdですか?(JSONなどから)。
Mikhail Batcer、2015年

2
Customer customer = entityManager.getReference(customerId, Customer.class); sale.setCustomer(customer);
JBニゼット2015年

5
とクラスの別のフィールドとの@EmbeddedId間に複合キーがある場合をどのように処理しますか?この場合、マッピングで両方の列を繰り返す必要がありますか?customerIdCustomer
ルイアモロス2017

2
はい@louisamoros、あなたはそれを繰り返すが、あなたは追加@MapsId("customerId")、参照stackoverflow.com/questions/16775055/hibernate-embeddedid-join
ダリボルFilus

71

誰かがすでにJPAアノテーションを配置しているが、関係を定義していないレガシーデータベースでスタックし、コードで使用するためにそれらを定義しようとしている場合、他のコードが原因でcustomerId @Columnを削除できない可能性があります。すでに直接参照している可能性があります。その場合、関係を次のように定義します。

@ManyToOne(optional=false)
@JoinColumn(name="productId",referencedColumnName="id_product", insertable=false, updatable=false)
private Product product;

@ManyToOne(optional=false)
@JoinColumn(name="customerId",referencedColumnName="id_customer", insertable=false, updatable=false)
private Customer customer;

これにより、関係にアクセスできます。ただし、関係を追加/更新するには、定義された@Column値を介して外部キーを直接操作する必要があります。これは理想的な状況ではありませんが、このような状況に直面した場合は、少なくともJPQLを正常に使用できるように関係を定義できます。


1
おかげで、これはまさに私が必要とするソリューションです。ManyToOneマッピングフィールドの他に、結合列に直接マップされるフィールドが必要です。
ryenus 14

これは、キーと主キーを同時にフォアするフィールドがある場合の正しいソリューションです。
AntuanSoft 2017年

あらまあ、あなたは私の日を救ったかもしれない...まさにこのケース
Clomez

22

これを使用して、私のために働きます:

@Column(name = "candidate_id", nullable=false)
private Long candidate_id;
@ManyToOne(optional=false)
@JoinColumn(name = "candidate_id", insertable=false, updatable=false)
private Candidate candidate;

おかげで、これは私が必要とする正確なソリューションです

optional = trueでも機能します。
オンドレイStašek

11
@Id
@Column(name = "COLUMN_NAME", nullable = false)
public Long getId() {
    return id;
}

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = SomeCustomEntity.class)
@JoinColumn(name = "COLUMN_NAME", referencedColumnName = "COLUMN_NAME", nullable = false, updatable = false, insertable = false)
@org.hibernate.annotations.Cascade(value = org.hibernate.annotations.CascadeType.ALL)
public List<SomeCustomEntity> getAbschreibareAustattungen() {
    return abschreibareAustattungen;
}

すでに列をマップしていて、誤って@JoinColumn hibernateのnamereferencesColumnNameに同じ値を設定した場合、同じ愚かなエラーが発生します

エラー:

原因:org.hibernate.MappingException:エンティティのマッピングで列が繰り返されています:com.testtest.SomeCustomEntity列:COLUMN_NAME(insert = "false" update = "false"でマップする必要があります)


2
ここでの重要なポイントは、エラーは「insert = false update = falseでマップする必要があります」とありますが、実際のパラメーター/メソッドは「insertable = false、updatable = false」である必要があるということです。
ナイトフクロウ

1

これが役立つことを願っています!

@OneToOne(optional = false)
    @JoinColumn(name = "department_id", insertable = false, updatable = false)
    @JsonManagedReference
    private Department department;

@JsonIgnore
    public Department getDepartment() {
        return department;
    }

@OneToOne(mappedBy = "department")
private Designation designation;

@JsonIgnore
    public Designation getDesignation() {
        return designation;
    }

0

すべての属性に対して1つのセッターとゲッターのみを提供するように注意してください。アプローチする最良の方法は、すべての属性の定義を書き留めてから、手動で行うのではなく、eclipse generate setterおよびgetterユーティリティを使用することです。このオプションは、右クリック->ソース->ゲッターとセッターを生成します。


0

つまり、エンティティクラスで列を2回マッピングしています。例を使って説明しています...

    @Column(name = "column1")
    private String object1;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "column1", referencedColumnName = "column1")
    private TableClass object2;

上記のコードスニペットの問題は、マッピングを繰り返していることです...

解決

マッピングは重要な部分であるため、削除する必要はありません。代わりに、削除します

    @Column(name = "column1")
    private String uniqueId;

TableClassのオブジェクトを作成してobject1の値を渡し、その中にObject1の文字列値を割り当てることもできます。

これは100%機能します。私はこれをPostgresとOracleデータベースでテストしました。


0

Grails 4(GORM)で親エンティティーではなく子エンティティーをマッピングすることにより、循環依存関係(親子エンティティー)を解決しました。

例:

Class Person {
    String name
}

Class Employee extends Person{
    String empId
}

//Before my code 
Class Address {
    static belongsTo = [person: Person]
}

//We changed our Address class to:
Class Address {
    static belongsTo = [person: Employee]
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.