Spring Data JPA:创建一个抽象存储库

时间:2012-03-28 12:39:08

标签: java spring spring-data spring-data-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 {}

是否有可能以某种方式为Animal配置JPA存储库?

我试过

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

5 个答案:

答案 0 :(得分:10)

我有类似的错误。我通过添加实体类到persistence.xml文件的映射来解决它。

所以也许可以在你的persistence.xml中添加这样的东西:

<persistence-unit>
...   
<class>yourpackage.Animal</class>
...
</persistence-unit>

答案 1 :(得分:7)

我遇到了这个问题,我找到了解决方案:您需要使用@MappedSuperclass @Inheritance,而不是两者都使用。像这样注释你的Animal类:

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

底层数据库方案将保持不变,现在您的通用AnimalRepository应该可以正常工作。持久性提供程序将进行内省并找出用于实际子类型的表。

答案 2 :(得分:2)

我猜你正在运行Hibernate作为持久性提供程序,对吧?我遇到了Hibernate这个场景的问题,因为针对Hibernate元模型的类型查找行为与JPA中指定的行为没有正确相矛盾(请参阅此bug for details)。所以看来你有两个选择:

  1. 将抽象超类也改为@Entity
  2. 切换到其他持久性提供程序

答案 3 :(得分:0)

您需要在webconfig中的@EntityScan中包含Animal类

答案 4 :(得分:-1)

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

}