Spring Данные JPA: создание абстрактного репозитория
Учитывая следующие классы:
@MappedSuperclass
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn(name="animalType",discriminatorType=DiscriminatorType.STRING)
@QueryExclude
public abstract class Animal {}
@Entity
@DiscriminatorValue("dog")
public class Dog {}
@Entity
@DiscriminatorValue("cat")
public class Cat {}
Возможно ли каким-либо образом настроить репозиторий JPA для Animal
?
Я пробовал
public interface AnimalRepository extends JpaRepository<Animal,Long>
Однако это не удается:
java.lang.IllegalArgumentException: Не управляемый тип: Animal
Есть ли способ настроить это?
Я хотел бы выполнять такие задачи, как:
@Autowired
private AnimalRepository repository;
public void doSomething()
{
Animal animal = repository.findById(123);
animal.speak();
}
Ответы
Ответ 1
У меня была аналогичная ошибка. Я решил это, добавив отображение моего класса объектов в файл persistence.xml.
Поэтому, возможно, добавьте что-то подобное вашему persistence.xml:
<persistence-unit>
...
<class>yourpackage.Animal</class>
...
</persistence-unit>
Ответ 2
У меня была эта точная проблема, и я нашел решение: вам нужно либо использовать @MappedSuperclass
ИЛИ @Inheritance
, но не оба вместе. Аннотируйте свой класс Animal
следующим образом:
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Animal {}
Базовая схема базы данных останется прежней, и теперь ваш общий AnimalRepository
должен работать. Поставщик сохранения выполнит интроспекцию и узнает, какую таблицу использовать для фактического подтипа.
Ответ 3
Я предполагаю, что вы используете Hibernate в качестве поставщика постоянного доступа, верно? Я столкнулся с проблемами с этим сценарием с Hibernate, так как поиск типов по сравнению с метамодели Hibernate не ведет себя правильно противоречащим тому, что указано в JPA (см. Эту ошибку для подробности). Итак, кажется, у вас есть два варианта:
- Измените абстрактный суперкласс как
@Entity
, а также
- Переключение на другой постоянный провайдер
Ответ 4
Tente desta maneira:
public interface RepositorioAnimal extends JpaRepository<Animal, Long> {
}
@Repository
@Transactional( readOnly = true )
public class RepositorioAnimal extends QueryDslJpaRepository<Animal, Long> implements RepositorioAnimal {
@Inject
public RepositorioAnimal( EntityManager em ) {
super( new JpaMetamodelEntityInformation<Animal, Long>( Animal.class, em.getMetamodel() ), em );
}
}
public interface ServicoAnimal {
void salvar( Animal entidade );
void remover( Animal entidade );
Animal carregar( Long id );
}
@Service
@Component
public class ServicoAnimalImpl implements ServicoAnimal {
@Inject
private RepositorioAnimal animal;
@Override
public void salvar( Animal entidade ) {
animal.save( entidade );
}
@Override
public void remover( Animal entidade ) {
animal.delete( entidade );
}
@Override
public Animal carregar( Long id ) {
return animal.findOne( id );
}
}
Ответ 5
Вам нужно включить Animal-класс в свой @EntityScan в свой веб-интерфейс