Hibernate - 自定义查询未通过 ManyToOne 单向关系的 child 参数找到实体

Posted

技术标签:

【中文标题】Hibernate - 自定义查询未通过 ManyToOne 单向关系的 child 参数找到实体【英文标题】:Hibernate - the custom query did not find the entity by the child parameter for ManyToOne unidirectional relation 【发布时间】:2018-08-09 05:23:52 【问题描述】:

我在使用子实体作为搜索参数检索实体时遇到问题。实体与多对一关系是单向的,每个对象都以 FetchType.LAZY 的形式获取。 当我通过子实体查找实体时,结果为空。但是当我设置为 Eager 时,它是正确的。

我的实体:

@NoArgsConstructor
@Getter
@Entity
@Table(name = "partner")
public class PartnerEntity implements Serializable 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String login;
    public PartnerEntity(String login) 
        this.login = login;
    



@NoArgsConstructor
@Getter
@Entity
@Table(name = "point")
public class PointEntity implements Serializable 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "partner_Id")
    private PartnerEntity partnerEntity;
    public PointEntity(PartnerEntity partnerEntity) 
        this.partnerEntity = partnerEntity;
    


@NoArgsConstructor
@Getter
@Entity
@Table(name = "orer")
public class OrdEntity implements Serializable 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "PAYMENT_POINT_ID")
    private PointEntity pointEntity;
    public OrdEntity(PointEntity pointEntity) 
        this.pointEntity = pointEntity;
    




@NoArgsConstructor
@ToString
@Getter
@Entity
@Table(name = "BL")
public class BLEntity implements Serializable 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "PARTNER_LOGIN", referencedColumnName = "login")
    private PartnerEntity partnerEntity;
    private String number;
    public BLEntity(PartnerEntity partnerEntity, String number) 
        this.partnerEntity = partnerEntity;
        this.number = number;
    

我正在寻找使用 OrdEntity 子实体的 BLEntity:

 final OrdEntity byId = ordRepo.findById(id);
 final PartnerEntity partnerEntity = order.getPointEntity().getPartnerEntity();
 final BLEntity blEntityResult= blRepo.findOneByNumberAndPartner(number, partnerEntity);

对象 partnerEntity 不为空,它是正确的对象。 我将 blEntityResult 设为 null,但如果我将 PointEntity fetch 更改为 FetchType.EAGER,则 blEntityResult 不为 null(正确)。

我在以下存储库中的自定义查询:

public interface BLRepo extends JpaRepository<BLEntity, Long> 
@Query("select b from BLEntity b where b.number = :number and b.partnerEntity= :partner")
BLEntity findOneByNumberAndPartner(@Param("number") String number, @Param("partner") PartnerEntity partner);

如果正在下载的伙伴对象不为空且正确,为什么会发生这种情况?

【问题讨论】:

为什么只生成Getter?塞特人呢? JPA 需要它们。 @SimonMartinelli 我添加了 Setter 但结果是一样的 【参考方案1】:

我认为你应该在两边添加映射, 因为@AllToMany=Lazy 和@ManyToAll = Eager 的默认获取类型。 只需在 PartnerEntity 中添加以下代码。

@OneToMany(mappedBy="partnerEntity" , fetch = FetchType.Eager )
 List<BLEntity> blEntity = new ArrayList<>();

【讨论】:

【参考方案2】:

我在PointEntity中将FetchType改为Eager:

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "partner_Id")
private PartnerEntity partnerEntity;

一切正常,但我不明白为什么它不适用于 PaymentType.Lazy。当我在寻找:

final PartnerEntity partnerEntity = order.getPointEntity().getPartnerEntity();

我得到正确的实体“PartnerEntity”,它具有正确的登录字段(登录字段的值为“test”)。

当我将日志级别设置为“TRACE”时,我看到 Hibernate 没有绑定正确的登录参数,它设置为 null 而不是“test”)为什么? :)

【讨论】:

以上是关于Hibernate - 自定义查询未通过 ManyToOne 单向关系的 child 参数找到实体的主要内容,如果未能解决你的问题,请参考以下文章

有 has_many 问题的 ActiveAdmin;未定义的方法'new_record?'

HiberNate5学习总结

Rails 4,通过连接表在has_many中指定自定义外键?

hibernate 映射文件属性自定义查询语句?

hibernate关联关系

hibernate one2many (单向关联)