I have a issue with Spring Data repositories.
When I deploy, I get an exception and it's because Spring Data tries to derive dynamically the method, but can't find in the Entity the corresponding property.
How can I put a custom method in the Custom Repository without this issue?
These are the involved components:
LocaleJpaImpl
: the EntityLocaleJpaRepositoryClient
: the business layer classinterface LocaleJpaRepository extends JpaRepository<LocaleJpaImpl, Long>, LocaleJpaRepositoryCustom
interface LocaleJpaRepositoryCustom
LocaleJpaRepositoryImplemented implements LocaleJpaRepositoryCustom
LocaleJpaRepositoryCustom
has a method:
List<String> catchLanguagesCombinations() throws DAOSystemException;
(LanguagesCombinations isn't a property of LocaleJpaImpl. For that motive is in the Custom Repository).
This exception:
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property languages found for type com.engine.i18n.domain.LocaleJpaImpl at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:74) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:326) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:352) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:306) at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:270) at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:244) at org.springframework.data.repository.query.parser.Part.<init>(Part.java:73) 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) 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) ... 33 more
This is the relevant code:
1. LocaleJpaImpl:
import java.io.Serializable; import javax.persistence.AttributeOverride; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import javax.xml.bind.annotation.XmlRootElement; import com.jpa.BaseEntityJpaSupport; @Entity @Table(name = "LOCALE") @XmlRootElement @AttributeOverride(name="id", column=@Column(name="LOCALE_ID")) @NamedQueries({ @NamedQuery(name = "Locale.findAll", query = "FROM LocaleJpaImpl l"), @NamedQuery(name = "Locale.findByLocaleId", query = "FROM LocaleJpaImpl l WHERE l.localeId = :localeId"), @NamedQuery(name = "Locale.findByLanguageCode", query = "FROM LocaleJpaImpl l WHERE l.languageCode = :languageCode") public class LocaleJpaImpl extends BaseEntityJpaSupport implements Serializable { private static final long serialVersionUID = 1L; //@Id //@Column(name = "LOCALE_ID") @Basic(optional = false) @NotNull @GeneratedValue(strategy = GenerationType.AUTO) private Integer localeId; @Size(max = 2) @Column(name = "LANGUAGE_CODE") private String languageCode; public LocaleJpaImpl(Integer localeId) { this.localeId = localeId; } public int getLocaleId() { return localeId; } public void setLocaleId(Integer localeId) { this.localeId = localeId; } public String getLanguageCode() { return languageCode; } public void setLanguageCode(String languageCode) { this.languageCode = languageCode; } }
3. interface LocaleJpaRepository
import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import com.engine.i18n.domain.LocaleJpaImpl; public interface LocaleJpaRepository extends JpaRepository<LocaleJpaImpl, Long>, LocaleJpaRepositoryCustom { @Query("FROM LocaleJpaImpl L WHERE L.languageCode = :languageCode") List<LocaleJpaImpl> findLocaleByLanguageCode(@Param("languageCode") String languageCode); }
4. interface LocaleJpaRepositoryCustom
import java.util.List; import com.util.DAOSystemException; public interface LocaleJpaRepositoryCustom { List<String> catchLanguagesCombinations() throws DAOSystemException; }
5. LocaleJpaRepositoryImplemented
import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import com.util.DAOSystemException; public class LocaleJpaRepositoryImplemented implements LocaleJpaRepositoryCustom { @PersistenceContext(unitName = "contentEntityManagerFactory") private EntityManager em; @SuppressWarnings("unchecked") @Override public List<String> catchLanguagesCombinations() throws DAOSystemException { return "result"; } }
I had a issue like this and my mistake was the name of the custom repository class:
If the name of your jpa repository interface is LocaleJpaRepository
, your new custom interface should be named LocaleJpaRepositoryCustom
, but the class that makes the override in the method must be named LocaleJpaRepositoryImpl
, as it follows:
public class LocalJpaRepositoryImpl implements LocalJpaRepositoryCustom{ @Override public void customMethod(){....} }
Basically, the implementation class of your custom interface should start with the name of your repository interface (JPARepository) ending with 'Impl' keyword.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With