如何将@OneToMany与JPA中的连接器表一起使用



我想为我的prestashop创建一个JPA数据库连接器,它可以自动将我的产品加载到我的商店中。我发现了对这一点很重要的表格:

通用产品信息表。

ps_product
===================
id_product
...

特性(产品特性(表

ps_feature
===================
id_feature
...

值表

ps_feature_value
===========
id_feature_value
id_feature
...

以及连接的表格

ps_feature_products
===================
id_feature
id_product
id_feature_value

我试着用@OneToMany和@JoinTable将列表输入我的模型

我的产品型号:


@Entity
@Table(name = "ps_product")
public class PSProduct {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_product")
private long id;
@OneToMany
????????
private List<PSFeatureValue> features;
...
}

我的价值模型:

@Entity
@Table(name = "ps_feature_value")
public class PSFeatureValue {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_feature_value")
private long id;
...
}

我该如何连接?如何将id_feature放入ps_feature_product表中?

尝试这种方式在表和表之间创建连接。

@Entity
@Table(name = "ps_product"){
public class PSProduct
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_product")
private long id;
@OneToMany(mappedBy = "product"
private List<PSFeatureValue> features;
...

}

@Entity
@Table(name = "ps_feature_value")
public class PSFeatureValue {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_feature_value")
private long id;
@ManyToOne
@JoinColumn(name = "psproduct_id")
private PSProduct product;    

}

在我看来。。。你的表格是这样链接的:

+ps_product ------+
,->| id_product <pk> |
|  | ...             |
|  +-----------------+
|
|  +ps_feature ------+                +ps_feature_value ------+
|  | id_feature <pk> |<----.          | id_feature_value <pk> |<---.
|  | ...             |     `-+--------| id_feature <fk>       |    |
|  +-----------------+       |        | ...                   |    |
|            ,---------------'        +-----------------------+    |
|            |                                                     |
|            |  +ps_feature_product-----+                          |
|            `--| id_feature <fk>       |                          |
`---------------| id_product <fk>       |                          |
| id_feature_value <fk> |--------------------------'
+-----------------------+

其中<pk>表示主键<fk>表示外键。IMHO你给字段起的名字有点糟糕,因为外键被称为与主键相同(我关注的是id_前缀(往往会让读者感到困惑,他们不知道什么是主键,什么是外键(

IMHO您在ps_feature_product.id_feature外键中有一个冗余指针,因为ps_feature可以通过导航id_feature_value外键,然后导航id_feature来获得。这是由ORM自动完成的,并将一些数据保存在数据库中。此外,如果您错误地更新了一个链接而没有更新另一个链接,这可能会导致数据库中的不一致性。

不管怎样,你有四个实体,而你只显示了2个。在我看来,你的结构应该如下:

@Entity
@Table(name = "ps_product")
public class PSProduct {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_product")
private long id;
@OneToMany(mappedBy = "id_product") /* I should have used just product */
private List<PSFeatureProduct> featuresProducts;
... /* getters/setters and other stuff */
}
@Entity
@Table(name = "ps_feature")
public class PSFeature {
@Id
// you don't say anything on this, so I'll not use @GeneratedValue here.
@Column(name = "id_feature")
private long id;
/* to obtain the values of a feature, we use the inverse mapping as
* the relationship is OneToMany */
@OneToMany(mappedBy = "id_feature")
/* no column required in the database for this property */
private List<PSFeatureValue> values;
/* the inverse relation of which products have this feature */
@OneToMany(mappedBy = "id_feature")
/* no column required in the database for this property */
private List<PSFeatureProduct> products;
... /* getters/setters and other stuff */
}
@Entity
@Table("ps_feature_value")
public class PSFeatureValue {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_feature_value")
private long id;
@ManyToOne
@Column(name = "id_feature")
private PSFeature feature;
/* the list of feature/product pairs that have this value */
@OneToMany(mappedBy = "id_feature_value")
private List<PSFeatureProduct> featureProducts;
... /* getters/setters and other stuff */
}
@Entity
@Table(name = "ps_feature_product")
public class PSFeatureProduct {
@Id
@Column(name = "id_feature_product") /* to be consistent */
privatre long id;
/* this field shouldn't be necessary, as the value can be obtained
* through the featureValue field below */
@ManyToOne
@Column(name = "id_feature")
private PSFeature feature;
@ManyToOne
@Column(name = "id_product")
private PSProduct product;
@ManyToOne
@Column(name = "id_feature_value")
private PSFeatureValue featureValue;
... /* getters/setters and other stuff */
}

一旦你有了一套完整的关系,你就可以消除那些你不会使用的关系,但有以下限制:

关系@OneToMany不拥有该关系(仅引用作为其所有者的逆@ManyToOne(,因此在不消除该关系的情况下,不能消除所引用的@ManyToOne关系。

相关内容

最新更新