【问题标题】:Hibernate JPA Repeated column in mapping for entity error for bi-directional mapping用于双向映射的实体错误映射中的 Hibernate JPA 重复列
【发布时间】:2020-12-26 12:51:28
【问题描述】:

我有两个实体,sale 和 sale_details。一次销售会有很多销售细节,但每个销售细节只属于一个销售,我当前的代码在映射实体错误时给了我一个重复列。

销售:

@Entity
@Table(name="Sales")
public class Sale implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "sale_id", nullable = false)
    private int sale_id;

    @Column(name = "promotionid_fk")
    private int promotionid_fk;

    @Column(name = "grand_total", nullable = false)
    private double grand_total;

    @Column(name = "salespersonid_fk", nullable = false)
    private int salespersonid_fk;

    @Column(name = "customerid_fk", nullable = false)
    private int customerid_fk;

    @Column(name = "storeid_fk", nullable = false)
    private int storeid_fk;

    @Column(name = "expected_date", nullable = false)
    private Date expected_date;

    @Column(name = "pickup_date")
    private Date pickup_date;

    @Column(name = "initial_deposit_date", nullable = false)
    private LocalDateTime initial_deposit_date;

    @Column(name = "initial_deposit_type", nullable = false)
    private String initial_deposit_type;

    @Column(name = "initial_deposit_amount", nullable = false)
    private double initial_deposit_amount;

    @Column(name = "final_payment_date")
    private LocalDateTime final_payment_date;

    @Column(name = "final_payment_type")
    private String final_payment_type;

    @Column(name = "final_payment_amount")
    private double final_payment_amount;

    //maps one sale to many sale details relationship
    @OneToMany(mappedBy = "sale", fetch = FetchType.LAZY)
    private List<SaleDetails> sale_detail_list; //stores list of sale_detail entries where FK saleid_fk field is the ID of this sale


    //default constructor, never used
    public Sale() {
    }

    //creates new sale
    public Sale(int promotionid_fk, double grand_total, int salespersonid_fk, int customerid_fk, int storeid_fk, Date expected_date, LocalDateTime initial_payment_date, String initial_payment_type, double initial_payment_amount) {
        this.promotionid_fk = promotionid_fk;
        this.grand_total = grand_total;
        this.salespersonid_fk = salespersonid_fk;
        this.customerid_fk = customerid_fk;
        this.storeid_fk = storeid_fk;
        this.expected_date = expected_date;
        this.initial_deposit_date = initial_payment_date;
        this.initial_deposit_type = initial_payment_type;
        this.initial_deposit_amount = initial_payment_amount;
    }

销售详情:

@Entity
@Table(name = "sale_Details")
public class SaleDetails implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "sale_detail_id")
    private int saleDetailId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "saleid_fk")
    private Sale sale;

    @Column(name = "saleid_fk")
    private int saleid_fk;

    @Column(name = "productid_fk")
    private int productid_fk;

    @Column(name = "quantity_sold")
    private int quantity_sold;

    public SaleDetails(){
    }

    public SaleDetails(int saleid_fk, int productid_fk, int quantity_sold){
        this.saleid_fk = saleid_fk;
        this.productid_fk = productid_fk;
        this.quantity_sold = quantity_sold;
    }

表结构:

我试图建立双向关系,我在这里做错了什么?据我了解,关系的拥有方是 sale_details 实体上的多对一,而销售实体中的 mappedby 只是引用反面已经存在映射?

完整的错误堆栈跟踪:

Unable to build Hibernate SessionFactory
org.hibernate.MappingException: Repeated column in mapping for entity: com.owl.server.entities.Sale_Details column: saleid_fk (should be mapped with insert="false" update="false")

【问题讨论】:

    标签: mysql database hibernate jpa


    【解决方案1】:

    我建议你关注java naming conventions。根据这个角色:

    :类名应该是名词,大小写混合,每个内部单词的首字母大写。

    变量:除变量外,所有实例、类和类常量都是大小写混合,首字母小写。内部单词以大写字母开头。

    因此,我建议您通过以下方式更正您的映射:

    @Entity
    @Table(name="Sales")
    public class Sale implements Serializable{
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "sale_id", nullable = false)
        private int saleId;
    
        @Column(name = "promotionid_fk")
        private int promotionId;
    
        // ...
    
        //maps one sale to many sale details relationship
        @OneToMany(mappedBy = "sale", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
        private List<SaleDetails> saleDetails;
    
    
        // default constructor, should be present
        // It is used by hibernate for entity instantiation
        public Sale() {
           saleDetails = new ArrayList<>();
        }
    
        // getters, setters
    
        // The addSaleDetail() and removeSaleDetail() are utility methods that
        // synchronize both ends whenever a child element is added or removed.
        public void addSaleDetail(SaleDetails saleDetail)
        {
            saleDetails.add(saleDetail);
            saleDetail.setSale(this);
        }
    
        public void removeSaleDetail(SaleDetails saleDetail)
        {
            saleDetails.remove(saleDetail);
            saleDetail.setSale(null);
        }
    }
    
    @Entity
    @Table(name = "Sale_Details")
    public class SaleDetails implements Serializable {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "sale_detail_id")
        private int saleDetailId;
    
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "saleid_fk")
        private Sale sale;
    
        // This should be removed
        // @Column(name = "saleid_fk")
        // private int saleid_fk;
    
        @Column(name = "productid_fk")
        private int productId;
    
        // ...
    
        public SaleDetails(){
        }
    
        // getters, setters
    }
    
    1. mappedBy中的值引用了关联另一方的字段名。

    2. 如果外键引用目标实体的主键字段,则可以省略使用referencedColumnName

    还有一个创建和保存新销售的示例:

    Sale sale = new Sale();
    sale.setPromotionId(1);
    
    // ...
    SaleDetails saleDetail1 = new SaleDetails();
    saleDetail1.setProductId(2);
    // set other fields except sale
    sale.addSaleDetail(saleDetail1);
    
    SaleDetails saleDetail2 = new SaleDetails();
    saleDetail2.setProductId(3);
    // set other fields except sale
    sale.addSaleDetail(saleDetail2);
    
    entityManager.persist(sale);
    

    【讨论】:

    • 好的,所以我做了更改,但仍然存在相同的错误。我不认为这是语法错误。
    • 您似乎没有提供完整映射,因为我无法从提供的映射中看到 saleid_fk 列重复的位置。
    • 呃,你想看看所有的代码吗?因为它比这个长,我只是把它剪下来让问题更容易阅读。
    • 我提供了完整的映射
    • 好吧,正如它在异常错误消息中建议的那样,您可以添加 @Column(name = "saleid_fk", insertable = false, updatable = false)@JoinColumn(name = "saleid_fk", insertable = false, updatable = false) ,但我不建议这样做。我建议完全删除 @Column(name = "saleid_fk") 并通过设置器设置所有与其他实体相关的实体。请注意,当您使用双向关系时,关联的双方应该是同步的。
    猜你喜欢
    • 2020-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    • 1970-01-01
    • 2014-12-29
    • 1970-01-01
    • 2016-04-19
    相关资源
    最近更新 更多