2012-03-28 20 views
13

Dadas las siguientes clases:primavera de datos JPA: Creación de un repositorio abstracta

@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 {} 

¿Es posible de alguna manera para configurar un repositorio para JPA Animal?

He intentado

public interface AnimalRepository extends JpaRepository<Animal,Long> 

Sin embargo esto no funciona con:

java.lang.IllegalArgumentException: No es un tipo administrado: Animal

¿Hay una manera de configurar ¿esta?

me gustaría ser capaz de realizar tareas como:

@Autowired 
private AnimalRepository repository; 

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

Respuesta

2

supongo que se está ejecutando Hibernate como su proveedor de persistencia, ¿verdad? He tropezado con problemas con este escenario con Hibernate, ya que la búsqueda de tipo en comparación con el metamodelo de Hibernate no se comporta correctamente contradiciendo lo especificado en el JPA (consulte este bug for details). Así que parece que tiene dos opciones aquí:

  1. Cambiar la superclase abstracta para ser un @Entity así
  2. Cambiar a un proveedor diferente persistente
10

tuve error similar. Lo resolví agregando mapeo de mi clase de entidad a mi archivo persistence.xml.

Así que tal vez añadir algo como esto a su persistence.xml:

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

+1 Me ayudó a resolver el problema similar al publicado .. gracias por el recordatorio .. – raksja

7

que estaba teniendo este problema exacto, y he encontrado la solución: Es necesario para cualquiera que use @MappedSuperclassO@Inheritance, no las dos juntas . Anote en su clase Animal así:

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

El esquema de base de datos subyacente seguirá siendo el mismo, y ahora su AnimalRepository genérica debería funcionar. El proveedor de persistencia hará la introspección y descubrirá qué tabla usar para un subtipo real.

+4

La única respuesta sensata hasta ahora. Las anotaciones de JPA son simplemente incorrectas. Además de lo que dijo, ¿por qué necesitaría una columna discriminatoria si hay una tabla por clase? No tiene sentido. –

0

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

} 
0

Es necesario incluir Animal clase en sus @EntityScan en su webconfig

Cuestiones relacionadas