使用 JPA 连接两个表

Posted

技术标签:

【中文标题】使用 JPA 连接两个表【英文标题】:Joining two tables with JPA 【发布时间】:2018-07-26 20:22:34 【问题描述】:

我正在尝试使用 @NamedQuery 加入两个表,AddressDivision。同一个地址有多个部门。目前我有 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_iddivision_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 已更改,因为 da 存在使得结果列表返回 Object[] 列表。对象DivisionAddress。因此,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-在非实体类中连接两个表

如何使用 JPA 和 Hibernate 连接两个不相关的实体

hibernate jpa将两个表与另一个表连接起来

如何使用 JPA Criteria API 连接不相关的实体

在 Spring Data JPA 中连接两个表实体

onetomany 单向与使用 jpa 的可连接设置