Given the following class structure:
@MappedSuperclass
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Animal {}
@Entity
public class Dog {}
@Entity
public class Cat {}
With Spring Data JPA, is it possible to use a generic Animal
Repository to persist an Animal
at runtime without knowing which kind of Animal
it is?
I know I can do it using a Repository-per-entity and by using instanceof
like this:
if (thisAnimal instanceof Dog)
dogRepository.save(thisAnimal);
else if (thisAnimal instanceof Cat)
catRepository.save(thisAnimal);
}
but I don't want to resort to the bad practice of using instanceof
.
I've tried using a generic Repository like this:
public interface AnimalRepository extends JpaRepository<Animal, Long> {}
But this results in this Exception: Not an managed type: class Animal
. I'm guessing because Animal
is not an Entity
, it's a MappedSuperclass
.
What's the best solution?
BTW - Animal
is listed with the rest off my classes in persistence.xml
, so that's not the problem.
You can only have one repository per entity... however, you can have multiple entities per table; thus, having multiple repositories per table.
CrudRepository is a Spring Data interface for generic CRUD operations on a repository of a specific type. It provides several methods out of the box for interacting with a database.
Crud Repository doesn't provide methods for implementing pagination and sorting. JpaRepository ties your repositories to the JPA persistence technology so it should be avoided. We should use CrudRepository or PagingAndSortingRepository depending on whether you need sorting and paging or not.
Each of these defines its own functionality: CrudRepository provides CRUD functions. PagingAndSortingRepository provides methods to do pagination and sort records. JpaRepository provides JPA related methods such as flushing the persistence context and delete records in a batch.
Actually the problem is with your mapping. You either use @MappedSuperclass
or @Inheritance
. Both together don't make sense. Change your entity to:
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Animal {}
Don't worry, the underlying database scheme is the same. Now one, general AnimalRepository
will work. Hibernate will do the introspection and find out which table to use for an actual subtype.
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