实体错误映射中的另一个重复列


111

尽管发布了其他所有文章,但在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
}

客户.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) {
        ...
    }

}

产品.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
}

Answers:


130

消息很清楚:映射中有重复的列。这意味着您两次映射了相同的数据库列。实际上,您有:

@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
我遇到相同的错误,但是我的情况有所不同。我的实体可以是一个或多个相同类型实体的父亲。孩子们有自己父亲的ID以及自己的唯一ID。如何解决这种循环依赖关系?
Ciri

@JBNizet然后如何保存特定商品的销售信息customerId?(例如,来自JSON)。
米哈伊尔·巴瑟

2
Customer customer = entityManager.getReference(customerId, Customer.class); sale.setCustomer(customer);
JB Nizet

5
您如何处理类与另一个字段@EmbeddedId之间有复合键的情况?在这种情况下,我需要映射中两个重复的列,对吗?customerIdCustomer
路易斯阿莫罗斯

2
@louisamoros是的,重复一下,但要添加@MapsId("customerId"),请参见stackoverflow.com/questions/16775055/hibernate-embeddedid-join
Dalibor 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

当您同时具有前键和主键的字段时,这是正确的解决方案。
AntuanSoft '17年

哦,天哪,您可能已经救了我的天……正是这种情况
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。
的OndrejStaš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中的namereferencedColumnName设置了相同的值, hibernate会给出相同的愚蠢错误

错误:

由以下原因导致:org.hibernate.MappingException:实体的映射中重复的列:com.testtest.SomeCustomEntity列:COLUMN_NAME(应映射为insert =“ false” update =“ false”)


2
对我而言,关键点在于错误提示“应使用insert = false更新= 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个setter和getter。最好的方法是写下所有属性的定义,然后使用eclipse generate setter和getter实用程序,而不是手动执行。该选项位于右键单击->源->生成Getter和Setter。


0

这意味着您要在实体类中映射两次列。举例说明...

    @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]
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.