web-dev-qa-db-fra.com

Spring Data, JPA @OneToMany Lazy fetch ne fonctionne pas dans Spring Boot

J'ai une relation @OneToMany Entre FabricRoll et FabricDefect.

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "fabric_roll_id", referencedColumnName = "fabric_roll_id")
private Set<FabricDefect> fabricDefects = new HashSet<>();

Le problème est quand j'obtiens FabricRoll par JpaRepository fonction

trouver tout()

l'associé FabricDefect est également chargé.

Je veux charger uniquement FabricRoll et FabricDefect devrait se charger lors de l'appel de la fonction getFabricDefect()

FabricRollServiceImpl, classe

@Component
public class FabricRollServiceImpl implements IFabricRollService{
    @Autowired
    FabricRollRepository fabricRollRepository;

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public List<FabricRoll> getAllFabricRoll() {
        FabricRoll fabricRoll1 = new FabricRoll();
        fabricRoll1.setBatchNo("34344");
        fabricRoll1.setLotNo("425");
        fabricRoll1.setPoNo("42");
        fabricRoll1.setRollLength(2343);
        fabricRoll1.setRollNo("356");
        fabricRoll1.setRollWidth(60);
        fabricRoll1.setStyleNo("354");

        FabricDefect fabricDefect = new FabricDefect();
        fabricDefect.setDefectNote("note");
        fabricDefect.setDefectPoint(3);
        fabricDefect.setSegment(3);
        fabricDefect.setYard(42);


        Set<FabricDefect> fabricDefects = new HashSet<>();
        fabricDefects.add(fabricDefect);


        fabricRoll1.setFabricDefects(fabricDefects);

        addFabricRoll(fabricRoll1);

        FabricRoll fabricRoll = null;


        return fabricRollRepository.findAll();
    }

@Override
public void addFabricRoll(FabricRoll fabricRoll) {
    fabricRollRepository.save(fabricRoll);
}

}

Point d'arrêt: enter image description here

Console: enter image description here

11
NIROB AECE

Classe FabricDefect:

@ManyToOne
@JoinColumn(name = "fabric_roll_id")
private FabricRoll roll;

Classe FabricRoll:

@OneToMany(mappedBy = "roll")
private Set<FabricDefect> fabricDefects;

Les collections sont par défaut chargées paresseusement, JPA interrogera la base de données uniquement lorsque la méthode getFabricDefects sera appelée. Vous pouvez le voir vous-même en activant la journalisation.

0
Manza

Vous n'avez pas besoin d'utiliser @JoinColumn, et vous n'avez pas besoin d'instancier fabricDefects

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<FabricDefect> fabricDefects ; 

Voir plus dans this question.

0
Azzabi Haythem

J'ai trouvé une solution dans ce tutoriel .

Vous devez modifier FabricRollOneToMany map comme ci-dessous:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "fabricRoll")
private Set<FabricDefect> fabricDefects;

FabricDefectManyToOne comme ci-dessous (n'oubliez pas de supprimer le champ fabric_roll_id si vous l'avez inclus dans votre entité):

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "fabric_roll_id")
private FabricRoll fabricRoll;

Et vous n'avez pas besoin d'ajouter @Transactional(propagation = Propagation.REQUIRED) avant getAllFabricRoll() fonction.

0
Huy Quang