JPA ManyToMany Join Table的所有属性都是PK [英] JPA ManyToMany Join Table has all attributes as PK

查看:116
本文介绍了JPA ManyToMany Join Table的所有属性都是PK的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Hibernate 3.3.1,并且正在建模这个示例表结构,但我在创建具有额外属性的连接表时遇到问题。

这是订单产品之间的多对多关系c $ c>表。连接表是 Order Detail 表。我遵循上面提到的方法

现在我有实体

  @Entity 
@Table(name =Orders)
public class Order {
@OneToMany(mappedBy =order)
private List<的OrderDetail>的OrderItems;
}

 @Entity 
@Table(name =PRODUCTS)
public class Product {
@OneToMany(mappedBy =product)
private列表与LT;&的OrderDetail GT;的OrderItems;
}



<$ p
@Command
@IdClass(OrderDetail.class)
@Table(name =ORDER_DETAIL)
public class OrderDetail实现Serializable {
@ Id
@Column(name =ORDER_ID)
private Long orderId;
@Id
@Column(name =PRODUCT_ID)
private long productId;

@Column(name =PRICE)
私人双重价格;

@Column(name =LAST_UPDATED_TIME)
私人日期lastUpdatedTime;

@ManyToOne
@JoinColumn(name =ORDER_ID)
私人订单;

@ManyToOne
@JoinColumn(name =PRODUCT_ID)
私人产品产品;
}

  public class OrderDetailId implements Serializable {
private Long orderId;
private long productId;
}

我使用Apache Derby进行测试,但遇到问题生成的表结构。

  CREATE TABLE ORDER_DETAIL(
PRODUCT_ID BIGINT不为NULL,
ORDER_ID BIGINT NOT NULL ,
LAST_UPDATED_TIME TIMESTAMP NOT NULL,
PRICE DOUBLE NOT NULL
);

CREATE INDEX SQL120323142938020 ON ORDER_DETAIL(PRODUCT_ID ASC);

CREATE UNIQUE INDEX SQL120323142937810 ON ORDER_DETAIL(PRODUCT_ID ASC,ORDER_ID ASC,LAST_UPDATED_TIME ASC,PRICE ASC);

ALTER TABLE ORDER_DETAIL ADD CONSTRAINT SQL120323142937810 PRIMARY KEY(PRODUCT_ID,ORDER_ID,LAST_UPDATED_TIME,PRICE);

ALTER TABLE ORDER_DETAIL ADD CONSTRAINT FK4A94AA82CC6D989A FOREIGN KEY(PRODUCT_ID)
REFERENCES PRODUCTS(PROD_ID);

它似乎创建了我所有的列作为主键。为什么会这样?

解决方案

您将实体的类用作IdClass的参数。这是不正确的。应使用Id类。此外,不需要为连接实体中的id分隔字段。



请参阅下面的代码。我不能保证它能在这样一个旧版本的Hibernate中工作,但对于永远不会有效的工作。值得尝试。如果你想使用JPA 2.0特性,至少要升级到3.5.X版本(或者更新的版本)并没有什么坏处。

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

$ b $实体
@IdClass(OrderDetailId.class)
@Table(name =ORDER_DETAIL)
public class OrderDetail implements Serializable {
@Id @ManyToOne @JoinColumn(name =ORDER_ID)
私人订单;

@Id @ManyToOne @JoinColumn(name =PRODUCT_ID)
私人产品产品;

@Column(name =PRICE)私人双重价格;
//也许你还想在这里使用@TemporalType
@Column(name =LAST_UPDATED_TIME)private Date lastUpdatedTime;
}

公共类OrderDetailId实现可序列化{
private Long order;
私人长款产品;
}

UPDATE 15/08/2017
在JPA 2.1及更高版本中,不需要为组合标识添加类,你可以这样做:

  @Entity 
@Table(name =ORDER_DETAIL)
public class OrderDetail实现Serializable {
@Id @ManyToOne @JoinColumn(name =ORDER_ID)
私人订单;

@Id @ManyToOne @JoinColumn(name =PRODUCT_ID)
私人产品产品;

@Column(name =PRICE)私人双重价格;
//也许你还想在这里使用@TemporalType
@Column(name =LAST_UPDATED_TIME)private Date lastUpdatedTime;
}


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's the many-to-many relationship between the Order and Product table. The join table is the Order Detail table. I followed the approach mentioned here.

Now I have the entities

@Entity
@Table(name = "Orders")
public class Order {
    @OneToMany(mappedBy="order")
    private List<OrderDetail> orderItems;
}

and

@Entity
@Table(name="PRODUCTS")
public class Product {
    @OneToMany(mappedBy="product")
    private List<OrderDetail> orderItems;
}

and

@Entity
@IdClass(OrderDetail.class)
@Table(name = "ORDER_DETAIL")
public class OrderDetail implements Serializable {
    @Id
    @Column(name="ORDER_ID")
    private Long orderId;
    @Id
    @Column(name="PRODUCT_ID")
    private Long productId;

    @Column(name = "PRICE")
    private double price;

    @Column(name = "LAST_UPDATED_TIME")
    private Date lastUpdatedTime;

    @ManyToOne
    @JoinColumn(name = "ORDER_ID")
    private Order order;

    @ManyToOne
    @JoinColumn(name = "PRODUCT_ID")
    private Product product;
}

and

public class OrderDetailId implements Serializable {
    private Long orderId;
    private Long productId;
}

I used Apache Derby to do the test, but I'm having trouble with the generated table structure.

CREATE TABLE ORDER_DETAIL (
        PRODUCT_ID BIGINT NOT NULL,
        ORDER_ID BIGINT NOT NULL,
        LAST_UPDATED_TIME TIMESTAMP NOT NULL,
        PRICE DOUBLE NOT NULL
    );

CREATE INDEX SQL120323142938020 ON ORDER_DETAIL (PRODUCT_ID ASC);

CREATE UNIQUE INDEX SQL120323142937810 ON ORDER_DETAIL (PRODUCT_ID ASC, ORDER_ID ASC, LAST_UPDATED_TIME ASC, PRICE ASC);

ALTER TABLE ORDER_DETAIL ADD CONSTRAINT SQL120323142937810 PRIMARY KEY (PRODUCT_ID, ORDER_ID, LAST_UPDATED_TIME, PRICE);

ALTER TABLE ORDER_DETAIL ADD CONSTRAINT FK4A94AA82CC6D989A FOREIGN KEY (PRODUCT_ID)
    REFERENCES PRODUCTS (PROD_ID);

It seems that it has created all of my columns as the primary key. Why is this so?

解决方案

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

这篇关于JPA ManyToMany Join Table的所有属性都是PK的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆