Spring Data JPA: создание абстрактного хранилища - PullRequest
13 голосов
/ 28 марта 2012

Учитывая следующие классы:

@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: Не управляемый тип: Животное

Есть ли способ настроить это?хотелось бы иметь возможность выполнять такие задачи, как:

@Autowired
private AnimalRepository repository;

public void doSomething()
{
    Animal animal = repository.findById(123);
    animal.speak();
}

Ответы [ 5 ]

10 голосов
/ 25 июля 2012

У меня была похожая ошибка.Я решил эту проблему, добавив сопоставление моего класса сущностей в мой файл persistence.xml.

Так что, возможно, добавьте что-то подобное в ваш файл persistence.xml:

<persistence-unit>
...   
<class>yourpackage.Animal</class>
...
</persistence-unit>
6 голосов
/ 15 января 2013

У меня возникла именно эта проблема, и я нашел решение: вам нужно либо использовать @MappedSuperclass ИЛИ @Inheritance, но не оба вместе.Аннотируйте ваш Animal класс следующим образом:

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Animal  {}

Базовая схема базы данных останется прежней, и теперь ваш универсальный AnimalRepository должен работать.Поставщик персистентности сделает самоанализ и выяснит, какую таблицу использовать для фактического подтипа.

2 голосов
/ 29 марта 2012

Полагаю, вы используете Hibernate в качестве своего поставщика персистентности, верно? Я наткнулся на проблемы с этим сценарием с Hibernate, так как поиск типов в метамодели Hibernate ведет себя неправильно, что противоречит тому, что указано в JPA (см. Эту ошибку для деталей ). Так что, похоже, у вас есть два варианта:

  1. Измените также абстрактный суперкласс на @Entity
  2. Переключиться на другого постоянного поставщика
0 голосов
/ 22 апреля 2016

Вам необходимо включить Animal-класс в ваш @EntityScan в вашей веб-конфигурации

0 голосов
/ 18 января 2013

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 );
    }

}
...