简体   繁体   中英

spring data JPA ignoring fetchmode on query methods

I have entities that have transitive relationships. So Entity A is mapped OneToMany to entity B and entity B is mapped OneToMany with entity C. Entity A has a property, userID, which is NOT the primary key and I need to fetch all records for a user ID from the DB. Due to the requirements, I want to fetch the child records of A and B eagerly. I have annotated the entities with FetchMode join and my Repository has a method findByUserId(int userId). I am using spring data JPA with hibernate as underlying ORM. Executing the above query method fires multiple queries, though I expected only one query with join to be fired.

I have already tried EntityGraphs, annotated my repository method with NamedQuery, tried mapping entities ManyToOne bidirectional but nothing seems to be working.

@Entity
@Table(name = "A_Master")
public class EntityA{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    private int userId;

    @OneToMany(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "FK_reservationId")
    @Fetch(FetchMode.JOIN)
    private List<EntityB> bEntities= new ArrayList<>();

}

@Entity
@Table(name = "Entity_B")
public class EntityB{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;
    @OneToMany(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "FK_journeyId")
    @Fetch(FetchMode.JOIN)
    private List<EntityC> cEntities = new ArrayList<>();
}

public interface ReservationRepository extends JpaRepository<EntityA, Integer>
{
    public List<EntityA> findByUserIdAndStatus(String userId);
}

FetchType defines how the collection is loaded. Is it going to be loaded immediatly or is it going to be loaded lazily (on demand).

In contrast FetchMode defines what will be the mechanism that will load the collection. When you have marked your collection with:

@OneToMany(cascade = CascadeType.PERSIST)
@Fetch(FetchMode.JOIN)

This is a nonsense because by default the fetchType of OneToMany is lazy, but you can't have JOIN mechanics on a lazy collection. In order to have a JOIN you need to have it set to EAGER.

The default FetchMode in hibernate is SELECT and this is the prefered fetchmode because it is very efficient with respect of cache usage where the access is based on a key. I would recommend you to use FetchType.Lazy with FetchMode.SELECT and enabled collection batching .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM