如何在Spring Data JPA投影中处理空指针异常

huangapple go评论79阅读模式
英文:

How to handle nullPointer in Spring Data JPA projections

问题

以下是翻译好的部分:

有没有想法是否有一种方法来处理在投影创建过程中发生的自定义方法以处理空值或任何其他异常?

在下面的JPQL查询中,我试图组合一个自定义对象,但是当列updatedBy下没有数据(在数据库中为null)时,由于无法继续处理空对象(getUpdatedBy -> getProfile -> getName),它会在内部失败。

@Query("select new john.home.com.demo.repository.projections.AgreementType(agreement.name, " +
        "agreement.type, " +
        "agreement.audit.createdBy.profile.name, " +
        "agreement.audit.updateDate, " +
        "agreement.audit.updatedBy.profile.name) from Agreement agreement")
List<AgreementType> findAgreementTypes();

这是我的实体:

Agreement:

@Setter
@Getter
@NoArgsConstructor
@Entity
@Table(name = "AGREEMENT")
public class Agreement {
    @Id
    @Column(name = "AGREEMENT_ID")
    private Long id;

    @Column(name = "NAME")
    private String name;

    @Column(name = "TYPE")
    private String type;

    @Embedded
    Audit audit;
}

Embeddable Audit:

@Getter
@Setter
@Embeddable
public class Audit {
    @OneToOne
    @JoinColumn(name = "CREATED_BY")
    private SystemProcess createdBy;

    @Column(name = "CREATION_DATE")
    private LocalDate creationDate;

    @Column(name = "UPDATE_DATE")
    private LocalDate updateDate;

    @OneToOne
    @JoinColumn(name = "UPDATED_BY")
    private SystemProcess updatedBy;
}

SystemProcess:

@Getter
@Setter
@Entity
@Table(name = "sys_process")
public class SystemProcess {
    @Id
    @Column(name = "PROCESS_ID")
    private Integer id;

    @Column(name = "PROCESS_MSG_TXT")
    private String messageText;

    @OneToOne
    @JoinColumn(name = "PROFILE_ID")
    private SystemProfile profile;
}

SystemProfile:

@Getter
@Setter
@Entity
@Table(name = "sys_profile")
public class SystemProfile {
    @Id
    @Column(name = "PROFILE_ID")
    private Integer id;

    @Column(name = "PROFILE_NM")
    private String name;
}

这是我使用的JPQL查询,但由于未知原因而无法工作:

@Query("select new dan.home.pl.demo.repository.projections.AgreementType(" +
            "agreement.name, " +
            "agreement.audit.createdBy.profile.name, " +
            "case when (agreement.audit.updatedBy is null) then 'Dummy Name' else agreement.audit.updatedBy.profile.name end" +
            ") from Agreement agreement")
List<AgreementType> findAgreementTypes();
英文:

Any thoughts if there's a way to have a custom method for handling null or any other exceptions happening during projection creation?

In the below JPQL query I'm trying to compose a custom object, but when there's no data under column updatedBy (it's null in database) - then it fails internally since cannot proceed with null object any further (getUpdatedBy -> getProfile -> getName).

@Query(&quot;select new john.home.com.demo.repository.projections.AgreementType(agreement.name, &quot; +
        &quot;agreement.type, &quot; +
        &quot;agreement.audit.createdBy.profile.name, &quot; +
        &quot;agreement.audit.updateDate, &quot; +
        &quot;agreement.audit.updatedBy.profile.name) from Agreement agreement&quot;)
List&lt;AgreementType&gt; findAgreementTypes();

Here are my entities:

Agreement:

@Setter
@Getter
@NoArgsConstructor
@Entity
@Table(name = &quot;AGREEMENT&quot;)
public class Agreement {
    @Id
    @Column(name = &quot;AGREEMENT_ID&quot;)
    private Long id;

    @Column(name = &quot;NAME&quot;)
    private String name;

    @Column(name = &quot;TYPE&quot;)
    private String type;

    @Embedded
    Audit audit;

Embeddable Audit

@Getter
@Setter
@Embeddable
public class Audit {
    @OneToOne
    @JoinColumn(name = &quot;CREATED_BY&quot;)
    private SystemProcess createdBy;

    @Column(name = &quot;CREATION_DATE&quot;)
    private LocalDate creationDate;

    @Column(name = &quot;UPDATE_DATE&quot;)
    private LocalDate updateDate;

    @OneToOne
    @JoinColumn(name = &quot;UPDATED_BY&quot;)
    private SystemProcess updatedBy;

SystemProcess:

@Getter
@Setter
@Entity
@Table(name = &quot;sys_process&quot;)
public class SystemProcess {
    @Id
    @Column(name = &quot;PROCESS_ID&quot;)
    private Integer id;

    @Column(name = &quot;PROCESS_MSG_TXT&quot;)
    private String messageText;

    @OneToOne
    @JoinColumn(name = &quot;PROFILE_ID&quot;)
    private SystemProfile profile;

SystemProfile:

@Getter
@Setter
@Entity
@Table(name = &quot;sys_profile&quot;)
public class SystemProfile {
    @Id
    @Column(name = &quot;PROFILE_ID&quot;)
    private Integer id;

    @Column(name = &quot;PROFILE_NM&quot;)
    private String name;
}

Here's the JPQL query I've used, however it doesn't work due to unknown reason

@Query(&quot;select new dan.home.pl.demo.repository.projections.AgreementType(&quot; +
            &quot;agreement.name, &quot; +
            &quot;agreement.audit.createdBy.profile.name, &quot; +
            &quot;case when (agreement.audit.updatedBy is null) then &#39;Dummy Name&#39; else agreement.audit.updatedBy.profile.name end&quot; +
            &quot;) from Agreement agreement&quot;)
    List&lt;AgreementType&gt; findAgreementTypes();

答案1

得分: 1

你可以使用 case 语句来实现这一点
查阅文档,链接在这里
https://docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html/ch11.html

类似于

case when agreement.audit is not null then agreement.audit.updatedBy.profile.name end
英文:

You can use the case statement to achieve this
Check the documentation here
https://docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html/ch11.html

Something like

case when agreement.audit is not null then agreement.audit.updatedBy.profile.name end

huangapple
  • 本文由 发表于 2020年9月14日 04:45:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/63875404.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定