Hibernate.com的Spring集成测试已为延迟加载的集合初始化

Hibernate.com的Spring集成测试已为延迟加载的集合初始化,hibernate,integration-testing,spring-test,Hibernate,Integration Testing,Spring Test,我有一个延迟加载的@OneToMany关系,我已经使用Hibernate.initialize()初始化了它。这里是我的实体 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

我有一个延迟加载的@OneToMany关系,我已经使用Hibernate.initialize()初始化了它。这里是我的实体

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;
@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;
@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);
}
public class OwnerResource {
 private Pet pet;
 private int petVisits
}
   @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();
}
}

我有这些实体的JPA存储库,PetRepository、OwnerRepository和VisitRepository

我有一个服务班

OwnerServiceImpl.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;
@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;
@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);
}
public class OwnerResource {
 private Pet pet;
 private int petVisits
}
   @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();
}
OwnerResource是一个简单的DTO

OwnerResource.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;
@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;
@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);
}
public class OwnerResource {
 private Pet pet;
 private int petVisits
}
   @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();
}
现在我正试图为OwnerServiceImpl#UpdateOwnerPetVisitions编写集成测试

OwnerServiceJPAIntegrationTests.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;
@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;
@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);
}
public class OwnerResource {
 private Pet pet;
 private int petVisits
}
   @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();
}
这个很好用

现在,如果我删除调用,则Hibernate.initialize(pet.getvisions())


从OwnerServiceImpl#updateOwnerPetVisits。测试用例现在应该失败了,但它仍然可以工作

您正在createNewOwner()中创建实体,那么为什么要延迟加载它们呢

如果要模拟延迟加载,必须在调用findPetById()之前清除EntityManger持久性上下文


createNewOwner()做什么?@SimonMartinelli我已经更新了代码。你能更具体地说明调用什么对象的方法吗?我添加了示例代码。但是我不知道以前有什么不清楚的地方?调用
EntityManager
上的
clear()
方法。谢谢你的澄清。