JPA ManyToMany Join Table has all attributes as PK

前端 未结 2 506
梦毁少年i
梦毁少年i 2021-01-03 11:16

I\'m using Hibernate 3.3.1 and am following along in modelling this sample table structure, but I\'m having trouble creating a join table with extra attributes.

It\

相关标签:
2条回答
  • 2021-01-03 11:35

    The code below seems to generate tables as desired, I have tested it on MySQL (just the table creation, not CRUD):

    @Entity
    @Table(name = "orders")
    public class Order {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @OneToMany(mappedBy = "orderDetailId.order")
        private List<OrderDetail> orderItems;
    
        //get set …..
    
    }
    
    @Entity
    @Table(name="products")
    public class Product {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @OneToMany(mappedBy = "orderDetailId.product")
        private List<OrderDetail> orderItems;   
    
        //get set ……
    }
    
    @Entity
    @Table(name = "order_detail")
    public class OrderDetail {
    
        @Id
        private OrderDetailId orderDetailId;
    
        private double price;
    
        @Temporal(TemporalType.TIMESTAMP)
        private Date lastUpdatedTime;
    
        //get set ….            
    }
    
    @Embeddable
    public class OrderDetailId implements Serializable{
    
        private Order order;
    
        private Product product;
    
        @ManyToOne(fetch=FetchType.LAZY)
        @Access(AccessType.PROPERTY)
        public Order getOrder() {
            return order;
        }
    
        public void setOrder(Order order) {
            this.order = order;
        }
    
        @ManyToOne(fetch=FetchType.LAZY)
        @Access(AccessType.PROPERTY)
        public Product getProduct() {
            return product;
        }
    
        public void setProduct(Product product) {
            this.product = product;
        }
    
        //hash code equals override 
    }
    

    Hibernate DEBUG details as below

    DEBUG: org.hibernate.tool.hbm2ddl.SchemaUpdate - create table order_detail (lastUpdatedTime datetime, price double precision not null, product_id bigint, order_id bigint, primary key (order_id, product_id)) ENGINE=InnoDB
    DEBUG: org.hibernate.tool.hbm2ddl.SchemaUpdate - create table orders (id bigint not null auto_increment, primary key (id)) ENGINE=InnoDB
    DEBUG: org.hibernate.tool.hbm2ddl.SchemaUpdate - create table products (id bigint not null auto_increment, primary key (id)) ENGINE=InnoDB
    DEBUG: org.hibernate.tool.hbm2ddl.SchemaUpdate - alter table order_detail add index FK23AE5A622128CF91 (order_id), add constraint FK23AE5A622128CF91 foreign key (order_id) references orders (id)
    DEBUG: org.hibernate.tool.hbm2ddl.SchemaUpdate - alter table order_detail add index FK23AE5A62EB201631 (product_id), add constraint FK23AE5A62EB201631 foreign key (product_id) references products (id)
    
    0 讨论(0)
  • 2021-01-03 11:50

    You use class of your entity as an argument to IdClass. That is not correct. Class of Id should be used. Additionally separate fields for id in join entity are not needed.

    Go for something like code below. I cannot guarantee that it works in such a old version of Hibernate, but works for sure in never ones. Worth of trying anyway. It would not hurt to update to at least 3.5.X version (or rather even fresher one) if you want to use JPA 2.0 features. Constructors/equals etc. are stripped away to save space.

    @Entity
    @Table(name = "Orders")
    public class Order {
        @Id Long id;
        @OneToMany(mappedBy="order")
        private List<OrderDetail> orderItems;
    }
    
    @Entity
    @Table(name="PRODUCTS")
    public class Product {
        @Id Long id;
        @OneToMany(mappedBy="product")
        private List<OrderDetail> orderItems;
    }
    
    @Entity
    @IdClass(OrderDetailId.class)
    @Table(name = "ORDER_DETAIL")
    public class OrderDetail implements Serializable {
        @Id @ManyToOne @JoinColumn(name = "ORDER_ID")
        private Order order;
    
        @Id @ManyToOne @JoinColumn(name = "PRODUCT_ID")
        private Product product;
    
        @Column(name = "PRICE") private double price;
        //Maybe you also want to use @TemporalType here
        @Column(name = "LAST_UPDATED_TIME") private Date lastUpdatedTime;
    }
    
    public class OrderDetailId implements Serializable {
        private Long order;
        private Long product;
    }
    

    UPDATE 15/08/2017 In JPA 2.1 and above you don't need to add a class for the composite Id and you can do it like this:

    @Entity
    @Table(name = "ORDER_DETAIL")
    public class OrderDetail implements Serializable {
        @Id @ManyToOne @JoinColumn(name = "ORDER_ID")
        private Order order;
    
        @Id @ManyToOne @JoinColumn(name = "PRODUCT_ID")
        private Product product;
    
        @Column(name = "PRICE") private double price;
        //Maybe you also want to use @TemporalType here
        @Column(name = "LAST_UPDATED_TIME") private Date lastUpdatedTime;
    }
    
    0 讨论(0)
提交回复
热议问题