I found myself struggling to implement customizable methods in Spring Data JPA.
For example, I have a Pet class, which has an Owner(Many to One rel.) What if I have a method to save(Pet pet, int ownerId). How can I get ownerId? Using Hibernate I just can getReference like that
public Pet save(Pet pet, int ownerId) {
if (!pet.isNew() && get(pet.getId(), ownerId) == null) {
return null;
}
pet.setUser(em.getReference(Owner.class, ownerId));
if (pet.isNew()) {
em.persist(pet);
return pet;
} else {
return em.merge(pet);
}
}
But using a Spring DJPA it's not so easy. I've created an interface that extends JpaRepository < Pet, Integer >, hoping that the parent class has a method called
saveWithReference, but i didn't find anything.. Any ideas guys?
You should have both a PetRepository and OwnerRepository both extending JpaRepository.
public interface PetRepository extends JpaRepository<Pet, Long> {}
and
public interface OwnerRepository extends JpaRepository<Owner, Long> {}
Using Spring Data JPA you can use the getOne method to get a reference, this in contrast to the findOne which will actually query the database.
The code you wrote using the EntityManager is basically the same and you should put that in a service method and instead of directly using the EntityManager use the 2 repositories.
@Service
@Transactional
public PetService {
private final PetRepository pets;
private final OwnerRepository owners;
public PetService(PetRepository pets, OwnerRepository owners) {
this.pets=pets;
this.owners=owners;
}
public Pet savePet(Pet pet, long ownerId) {
if (!pet.isNew() && get(pet.getId(), ownerId) == null) {
return null;
}
pet.setUser(owners.getOne(ownerId));
return pets.save(pet);
}
}
Something like that should do the trick. NO need to implement methods in your repository.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With