On the problem of Spring Data JPA soft deletion and associated query Number1

@Entity
@Getter
@Setter
@ToString
@Table(name = "order")
public class Order {
    @Id
    private Long id;
    @Column(name = "account_id")
    private Long accountId;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "account_id", insertable = false, updatable = false)
    private Account account;
}
@Entity
@Getter
@Setter
@ToString
@Table(name = "account")
@SQLDelete(sql = "update account set is_deleted=1 where id=?")
@Where(clause = "is_deleted=0")
public class Account {
    @Id
    private Long id;
    private String account;
    
    @Column(name = "is_deleted")
    private Boolean deleted;
}

as above, the two entity classes

question 1: when querying Order, the final generated SQL statement is not a JOIN table query, but a two-step query. First check order and then go to account table and interior query through account_id. This will give rise to the problem of account 1. Is this not true only for lazy queries?

question 2:Account uses soft deletion, which is annotated by @ Where (clause = "is_deleted=0") with this condition in every query. How can you set an exception, such as querying Order and checking Account in association? if this condition is taken, an EntityNotFoundException exception will occur because some records in account have been soft deleted.


problem 1 has found a solution. Let's share it with
through @ NamedEntityGraph and @ EntityGraph annotations

add comments to the Order class

@NamedEntityGraph(name = "Order.account", attributeNodes = {
        @NamedAttributeNode("account")
})
public class Order {
    @Id
    private Long id;
    @Column(name = "account_id")
    private Long accountId;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "account_id", insertable = false, updatable = false)
    private Account account;
}

then add the annotation @ EntityGraph
to the query method of the corresponding Repository, for example:

public interface OrderRepository extends JpaRepository<Order, Long> {
    @EntityGraph(value = "Order.account")
    List<Order> findAll();
}

so the query statement generated in the end uses LEFT JOIN, which solves the problem of Number1

.
Menu