【问题标题】:Another Repeated column in mapping for entity error实体错误映射中的另一个重复列
【发布时间】:2013-02-11 03:46:09
【问题描述】:

尽管有其他所有帖子,但我无法在 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
}

【问题讨论】:

    标签: hibernate jakarta-ee mappingexception


    【解决方案1】:

    信息很明确:映射中有重复的列。这意味着您将相同的数据库列映射了两次。事实上,你有:

    @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()
    

    【讨论】:

    • 我得到同样的错误,但我的情况有点不同。我的实体可以是一个或多个相同类型实体的父亲。孩子们有关于他们父亲的身份的参考以及他们自己的唯一身份。如何解决这样的循环依赖?
    • @JBNizet 我怎样才能保存某个特定customerId 的销售? (例如来自 JSON)。
    • Customer customer = entityManager.getReference(customerId, Customer.class); sale.setCustomer(customer);
    • 如何处理在customerIdCustomer 类的另一个字段之间有一个@EmbeddedId 复合键的情况?在这种情况下,我需要映射中的两个重复列,对吗?
    • @louisamoros 是的,你重复一遍,但你添加@MapsId("customerId"),见stackoverflow.com/questions/16775055/hibernate-embeddedid-join
    【解决方案2】:

    如果您被遗留数据库困住,其中有人已经放置了 JPA 注释但没有定义关系,而您现在正试图定义它们以在您的代码中使用,那么您可能无法删除 customerId @987654321 @ 因为其他代码可能已经直接引用了它。在这种情况下,定义如下关系:

    @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。

    【讨论】:

    • 谢谢,这正是我需要的解决方案,除了ManyToOne映射字段,我还需要一个直接映射到join列的字段。
    • 当你有一个同时是外键和主键的字段时,这是正确的解决方案。
    • 天哪,你可能拯救了我的一天......正是这种情况
    【解决方案3】:
    @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 设置了相同的值,那么休眠会给出同样的愚蠢错误

    错误:

    原因:org.hibernate.MappingException:实体映射中的重复列:com.testtest.SomeCustomEntity 列:COLUMN_NAME(应使用 insert="false" update="false" 进行映射)

    【讨论】:

    • 对我来说一个关键点是错误说“应该用 insert=false update=false 映射”,但实际的参数/方法应该是“insertable=false, updatable=false”。
    【解决方案4】:

    注意为任何属性只提供 1 个 setter 和 getter。最好的方法是写下所有属性的定义,然后使用 eclipse 生成 setter 和 getter 实用程序,而不是手动执行。该选项来自右键单击-> 源-> 生成 Getter 和 Setter。

    【讨论】:

      【解决方案5】:

      使用这个,对我有用:

      @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 也可以工作。
      【解决方案6】:

      希望这会有所帮助!

      @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;
          }
      

      【讨论】:

        【解决方案7】:

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

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

        上面代码sn-p的问题是我们在重复映射...

        解决方案

        由于映射是一个重要部分,您不想删除它。相反,您将删除

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

        你仍然可以通过创建一个TableClass的对象并在其中分配Object1的String值来传递object1的值。

        这 100% 有效。我已经用 Postgres 和 Oracle 数据库对此进行了测试。

        【讨论】:

          【解决方案8】:

          我们通过在 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]
          }
          

          【讨论】:

            猜你喜欢
            • 2020-06-22
            • 1970-01-01
            • 2019-02-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多