2012-12-19 8 views
35

Ho un'entità multimediale che ha alcuni campi base per i file caricati dall'utente. Per salvare i byte dei file caricati, voglio creare un repository personalizzato che contenga tale funzionalità. Seguendo i passaggi della Spring documentation, ho creato un'interfaccia che assomiglia a questo:Nessuna proprietà trovata per errore di tipo quando si tenta di creare un repository personalizzato con Spring Data JPA

public interface MediaBytesRepository 
{ 
    public byte[] getBytes(Media media) throws IOException; 
    public void saveBytes(Media media, byte[] bytes) throws IOException; 
    public void appendBytes(Media media, byte[] bytes) throws IOException; 
    public void deleteBytes(Media media) throws IOException; 
    public boolean bytesExist(Media media) throws IOException; 
} 

Poi ho fornito un'implementazione per questa interfaccia denominata MediaBytesRepositoryImpl

Con questo, ho poi creato la seguente interfaccia:

public interface MediaRepository extends JpaRepository<Media, Long>, MediaBytesRepository 
{ 
} 

Ora, quando inizio il server, ottengo il seguente stack trace:

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mediaRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Could not create query metamodel for method public abstract void com.foo.bar.core.media.MediaBytesRepository.saveBytes(com.foo.bar.core.media.Media,byte[]) throws java.io.IOException! 
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:149) 
..... 
Caused by: java.lang.IllegalArgumentException: Could not create query metamodel for method public abstract void com.foo.bar.core.media.MediaBytesRepository.saveBytes(com.foo.bar.core.media.Media,byte[]) throws java.io.IOException! 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:92) 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:162) 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:68) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:280) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:148) 
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:125) 
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:41) 
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142) 
    ... 20 more 
Caused by: java.lang.IllegalArgumentException: No property save found for type class com.foo.bar.core.media.Media 
    at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:73) 
    at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:92) 
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:319) 
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:333) 
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:301) 
    at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:265) 
    at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:239) 
    at org.springframework.data.repository.query.parser.Part.<init>(Part.java:70) 
    at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:180) 
    at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:260) 
    at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:240) 
    at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:68) 
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:57) 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:90) 
    ... 27 more 

Ho trovato questo similar post, ma i suggerimenti lì (tutti nello stesso pacchetto, convenzione di denominazione) sono cose che sto già facendo. Tutte le mie classi multimediali e le interfacce sono nello stesso pacchetto e sto usando il suffisso "Impl".

Qualcuno può per favore chiarire perché sto ricevendo questo errore e come posso risolvere il problema? Grazie.

risposta

69

Hai scritto:

i suggerimenti lì (tutti nella stessa confezione, Naming Convention) sono cose che sto già facendo.

No, non è così.

Rinomina MediaBytesRepository a MediaRepositoryCustom.

E ovviamente è necessaria un'implementazione di MediaRepositoryCustom con il nome MediaRepositoryImpl.

+19

Sembra che abbia frainteso il modo in cui le cose dovrebbero essere nominate. Dopo la tua risposta ho guardato di nuovo la documentazione e ho capito che il nome della mia classe di implementazione deve essere il nome dell'interfaccia Spring Data + "Impl" e non il nome della mia interfaccia + "Impl". Quindi, sono stato in grado di mantenere il nome della mia interfaccia 'MediaBytesRepository' e ho dovuto solo nominare l'implementazione' MediaRepositoryImpl' invece di 'MediaBytesRepositoryImpl'. Grazie per l'aiuto. – dnc253

+24

Fatto lo stesso errore ... Per riassumere dovrebbe essere: 1) YourInterfaceName 2) YourInterfaceNameCustom 3) YourInterfaceNameImpl –

+1

Hai salvato il mio giorno. Funzionando come il fascino –

6

È necessario denominare la classe impl come "InterfaceNameImpl". Postfix di default per l'attuazione è Impl, si può cambiare come ci piace:

<repositories base-package="com.acme.repository" repository-impl-postfix="FooBar" /> 

Il nome di interfacce personalizzate non importa.

+0

È questo nel pom? – santafebound