EntityNotFoundException LEFT JOIN JPA - Hibernate

时间:2017-10-13 18:07:28

标签: java hibernate jpa

  

线程中的异常" main" javax.persistence.EntityNotFoundException:   无法找到ID为00001388000307

的CNPJ

我正在阅读jpa文档,我读到当尝试访问(通过EntityManger接口的getReference方法)并且实体不存在时抛出此异常

Thrown by the persistence provider when an entity reference obtained by EntityManager.getReference is accessed but the entity does not exist.

我有这个实体:Salesman e CNPJ。很可能存在许多具有相同CNPJ的销售人员,换句话说,关系@ManyToOne

这种关系正常,好的。

但是,当我尝试执行查询时

select r from Salesman r join fetch r.yearMonth left join fetch r.cnpj

为销售人员提供其yearMonth(它正在工作!)的关系及其CNPJ关系,抛出异常,当我尝试进行LEFT JOIN时,我提到过。

当我没有执行LEFT JOIN时,效果很好,所有推销员都带着他的CNPJ并且没有例外,BUUUUT,有些推销员没有CNPJ,我也必须带他们,有必要做LEFT JOIN

@Entity
public class Salesman{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @JoinColumn(name = "year_month")
    @ManyToOne
    private YearMonth yearMonth;

    private String cnpjS;

    @JoinColumn(name = "cnpj")
    @ManyToOne
    private CNPJ cnpj;

    public AnoMes getYearMonth() {
        return yearMonth;
    }

    public CNPJ getCnpj() {
        return cnpj;
    }

}

@Entity
public class CNPJ {

    @Id
    @Column(name = "CCG", length = 14)
    private String ccg;

    public String getCcg() {
        return ccg;
    }
}

Hibernate生成的选择:

select *
from salesman s
inner join yearmonth y on s.ano_mes = y.id 
left outer join cnpj c on s.cnpjS = c.CCG

此咨询返回此值,rcnpj是来自Salesman的cnpj,而bcnpj来自CNPJ。一些推销员带来了CNPJ NULL,我认为这是问题所在。我不这么认为。

The return of the select

2 个答案:

答案 0 :(得分:0)

尝试使用<property name="show_sql">true</property>启用hibernate sql日志记录,以查看真正的查询(本机,在db上调用)的样子,也许在hibernate处理之后有一个内部联接。

要进行更改,您可以为您的关系尝试@Column(nullable=true)注释,或@Fetch(FetchMode.SELECT)查看真实查询的更改方式。

原因是你引用了ID为00001388000307的cnpj,但这样的cnpj行并不存在。

您可以尝试使用@NotFound(action=NotFoundAction.IGNORE)来跳过此类错误,但建议您修复处理异常的数据库。

答案 1 :(得分:0)

您正在使用Salesman表上的cnpj列作为外键和值列。在这种情况下,@ staszko032使用@NotFound(action=NotFoundAction.IGNORE)的建议看起来会像你期望的那样工作

但我认为如果可能的话你应该重构你的模型。你总是可以创建一个CNPJ实体,在这种情况下,你不会有没有向CNPJ创建的Salesman,并且可以使用INNER JOIN,或者使用2列,当Salesman没有的时候会使用具体相关CNPJ(值为字符串),另一个具有(外键)