使用 JPA 连接两个表
Posted
技术标签:
【中文标题】使用 JPA 连接两个表【英文标题】:Joining two tables with JPA 【发布时间】:2018-07-26 20:22:34 【问题描述】:我正在尝试使用 @NamedQuery
加入两个表,Address
和 Division
。同一个地址有多个部门。目前我有
Division.java:
@Entity
@Table(name="division")
@NamedQuery(name="Division.mailingAddress", query="SELECT d, a from Division d LEFT JOIN d.addresses a")
public class Division implements Serializable
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name="division_id")
private Short divisionId;
@Basic(optional = false)
@Column(name="division_name")
private String divisionName;
@Basic(optional = false)
@Column(name="address_id")
private Short addressId;
@OneToMany(mappedBy="divisionMailingAddress")
private List<Address> addresses;
//getters and setters
地址.java:
@Entity
@Table(name="address")
public class Address implements Serializable
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GeneratedType.IDENTITY)
@Basic(optional = false)
@Column(name = "address_id")
private Short addressID;
@Basic(optional = false)
@Column(name = "mailing_address")
private String mailingAddress;
@ManyToOne
private Division divisionMailingAddress;
我运行它时遇到的错误是:
Unknown column 't0.DIVISIONMAILINGADDRESS_division_id' in 'on clause'
我想要得到的是在 mysql 中有效的这条线:
SELECT * FROM (division d join address a on d.address_id = a.address_id);
目前,JPA 正在将命名查询解析为:SELECT t1."all columns", t0."all columns" from division t1 LEFT OUTER JOIN address t0 ON (t0.DIVISIONMAILINGADDRESS_division_id = t1.division_id)
我在做什么有什么问题? JPA 是否希望加入来自地址与部门?如何让address_id
与division_id
之间的通话被拨打?
更新:
在极大的帮助下,这两个类已被更改以实现我想要的结果。
Division.java:
@Entity
@Table(name="division")
@NamedQuery(name="Division.mailingAddress", query="SELECT d from Division d LEFT JOIN d.addressesM2O a")
public class Division implements Serializable
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name="division_id")
private Short divisionId;
@Basic(optional = false)
@Column(name="division_name")
private String divisionName;
@Basic(optional = false)
@Column(name="address_id")
private Short addressId;
@ManyToOne(targetEntity = Address.java)
@JoinColumn(name = "address_id", updatable=false, insertable=false)
private Address addressesM2O;
//getters and setters
地址.java:
@Entity
@Table(name="address")
public class Address implements Serializable
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GeneratedType.IDENTITY)
@Basic(optional = false)
@Column(name = "address_id")
private Short addressID;
@Basic(optional = false)
@Column(name = "mailing_address")
private String mailingAddress;
@OneToMany(mappedBy="addressesM2O")
private List<Division> divisionO2M;
@NamedQuery
已更改,因为 d
和 a
存在使得结果列表返回 Object[]
列表。对象Division
和Address
。因此,d
被保留,a
被从 @NamedQuery
中删除。
【问题讨论】:
【参考方案1】:我认为问题在于您在 Address 类中提及 @ManyToOne
时没有提及 @JoinColumn
,因此在进行连接时 JPA 本身正在创建外键 DIVISIONMAILINGADDRESS_division_id。
尝试在下面的 Address 类中提及 ManyToOne 关系,如果出现任何问题,请告诉我:
@ManyToOne(targetEntity = Division.class)
@JoinColumn(name= "division_id")//basically the name of the column here should be same as the one mentioned in your database
【讨论】:
我添加了targetEntity
,但仍然出现上述错误。当还添加 JoinColumn
时,我得到一个不同的错误。 Multiple writable mappings exist for the field [address.division_id]. Only one may be defined as writable, all others must be read-only.
如何将条目设为只读?
在JoinColumn注解中添加updatable =false, insertable =false
添加这两个量词效果很好。谢谢。
我发现的另一件事,我需要发布更新,是 @ManyToOne
工作我不需要在 @NamedQuery
中包含 Address
。【参考方案2】:
对我有用的是在address
表中将@OneToMany
和@ManyToOne
更改为@OneToOne
和@PrimaryKeyJoinColumn
。代码更新如下:
Division.java 改为:
@OneToOne(mappedBy="divisionMailingAddress")
private Address address;
Address.java 改为:
@OneToOne
@PrimaryKeyJoinColumn
private Division divisionMailingAddress;
【讨论】:
这给出了误报。这将尝试使用 Address 中的 PKID,并尝试加入 Division 中的 PKID。如果两者都使用相同的 PKID,那么很好。否则会产生误报。以上是关于使用 JPA 连接两个表的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 JPA 和 Hibernate 连接两个不相关的实体