1

I have a lazy loaded @OneToMany relationship which I have initialized using Hibernate.initialize(). Here are my Entities.

Pet.java

@Entity
@Table(name = "pets")
public class Pet {

@Column(name = "birth_date")
private Date birthDate;

@ManyToOne
@JoinColumn(name = "type_id")
private PetType type;

@OneToOne
@JoinColumn(name = "owner_id")
private Owner owner;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "pet", fetch = FetchType.LAZY)
private Set<Visit> visits;

}

Visit.java

@Entity
@Table(name = "visits")
public class Visit {

@Column(name = "visit_date")
private Date date;

@NotEmpty
@Column(name = "description")
private String description;

@ManyToOne
@JoinColumn(name = "pet_id")
private Pet pet;

}

I have JPA Repositories for these Entities, PetRepository, OwnerRepository and VisitRepository.

I have one @Service class.

OwnerServiceImpl.java

@Override
@Transactional
public void updateOwnerPetVisits(int ownerId) throws DataAccessException {

Owner owner = ownerRepository.findById(ownerId);

int petId = owner.getPet().getPetId();

Pet pet = findPetById(petId);

Hibernate.initialize(pet.getVisits());

OwnerResource ownerResource = new OwnerResource();
ownerResource.setPet(pet);
ownerResource.setPetVisits(pet.getVisits().size());

}

private Pet findPetById(int id) throws DataAccessException {
return petRepository.findById(id);
}

OwnerResource is a simple DTO.

OwnerResource.java

public class OwnerResource {
 private Pet pet;
 private int petVisits
}

Now I was trying to write the Integration Test for the OwnerServiceImpl#updateOwnerPetVisits.

OwnerServiceJPAIntegrationTests.java

   @ContextConfiguration(locations = {"classpath:spring/spring-jpa.xml"})
   @RunWith(SpringJUnit4ClassRunner.class)
   public class OwnerServiceJPAIntegrationTests {

     @Autowired
     OwnerRepository ownerRepository;

     @Autowired
     PetRepository petRepository;

     @Autowired
     OwnerService ownerService;


     @Test
     public void testUpdateOwnerPetVisits(){

      Owner owner = createNewOwner();

      int petId = owner.getPet().getPetId();

      Pet pet = findPetById(petId);

      assertFalse(Hibernate.isInitialized(pet.getVisits());

      ownerService.updateOwnerPetVisits(owner.getOwnerId());

      assertTrue(Hibernate.isInitialized(pet.getVisits());

    }


private Owner createNewOwner()  {

Pet pet  = new Pet();
pet.setBirthDate(today);
petRepository.add(pet); // entityManager.persist();

Visit visit1 = new Visit();
visit1.setDate(today);
visit1.setDescription("T");
visit1.setPet(pet); 
visitRepository.add(visit1); // entityManager.persist();

Visit visit2 = new Visit();
visit2.setDate(today);
visit2.setDescription("P");
visit2.setPet(pet); 
visitRepository.add(visit2); // entityManager.persist();

Owner owner = new Owner();
owner.setPet(pet);
ownerRepository.add(owner); // entityManager.persist();
}

This works fine.

Now if I remove the call, Hibernate.initialize(pet.getVisits());

from OwnerServiceImpl#updateOwnerPetVisits. The test case should fail now but it still works.

2
  • What does createNewOwner() do? Commented Dec 13, 2017 at 16:07
  • @SimonMartinelli I have updated the code. Commented Dec 13, 2017 at 16:39

1 Answer 1

2

You are creating the entities in createNewOwner() so why should they be lazy loaded?

If you want to simulate lazy loading you must clear the EntityManger persistence context before calling findPetById()

 @Test
 public void testUpdateOwnerPetVisits(){

  Owner owner = createNewOwner();

  int petId = owner.getPet().getPetId();

  // Clears the persistence context
  entityManager.clear();

  Pet pet = findPetById(petId);

  assertFalse(Hibernate.isInitialized(pet.getVisits());

  ownerService.updateOwnerPetVisits(owner.getOwnerId());

  assertTrue(Hibernate.isInitialized(pet.getVisits());

}
Sign up to request clarification or add additional context in comments.

3 Comments

Can you be more specific about what methods to call on what objects exactly?
I added the example code. But I don't see what was not clear before?
Calling the clear() method on the EntityManager. Thanks for clarifying.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.