我有以下课程:
@Entity @Table(name = "my_entity") @JsonIgnoreProperties(ignoreUnknown = true) public class MyEntity { @EmbeddedId private Pk id; public Pk getId() { return id; } public void setId(Pk id) { this.id = id; } } @Embeddable public class Pk implements Serializable { private static final long serialVersionUID = -3090221844117493661L; private Integer type; private String userId; public Pk() { } public Pk(String userId, Integer type) { this.setUserId(userId); this.setType(type); } public Integer getType() { return type; } public String getUserId() { return userId; } public void setType(Integer type) { this.type = type; } public void setUserId(String userId) { this.userId = userId; } // Auto-generated by Eclipse. @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((type == null) ? 0 : type.hashCode()); result = prime * result + ((userId == null) ? 0 : userId.hashCode()); return result; } // Auto-generated by Eclipse. @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Pk other = (Pk) obj; if (type != other.type) return false; if (userId == null) { if (other.userId != null) return false; } else if (!userId.equals(other.userId)) return false; return true; } } public interface MyEntityRepository extends JpaRepository<MyEntity, Pk> { List<MyEntity> findAllByUserId(String userId); }
当我初始化Spring Data JPA时,出现错误:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myEntityRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property user found for type MyEntity! at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1512) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:615) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:73) at com.myproject.backend.common.ServiceContext.start(ServiceContext.java:293) at com.myproject.run(AbstractServiceContainer.java:55) at com.myproject..run(AbstractServiceContainer.java:1) at io.dropwizard.cli.EnvironmentCommand.run(EnvironmentCommand.java:42) at io.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:76) at io.dropwizard.cli.Cli.run(Cli.java:70) at io.dropwizard.Application.run(Application.java:72) at com.myproject..main(CombinedServiceContainer.java:106) Caused by: org.springframework.data.mapping.PropertyReferenceException: No property user found for type MyEntity! at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:359) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307) at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:270) at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:241) at org.springframework.data.repository.query.parser.Part.<init>(Part.java:76) at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:213) at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:321) at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:301) at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:85) at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:60) at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:91) at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:168) at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:69) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:320) at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:169) at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:224) at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:210) at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1571) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1509) ... 18 more
问题: Spring Data JPA是否不支持对主键的子集进行查询? 还是我需要为此实现自定义存储库方法?
好的,我还尝试使用以下方法执行此操作@IdClass:
@IdClass
@Entity @Table(name = "my_entity") @JsonIgnoreProperties(ignoreUnknown = true) @IdClass(Pk.class) public class MyEntity { @Id private Integer type; @Id private String userId; public Pk getId() { return id; } public void setId(Pk id) { this.id = id; } } @IdClass(Pk.class) public class Pk implements Serializable { private static final long serialVersionUID = -3090221844117493661L; private Integer type; private String userId; public Pk() { } public Pk(String userId, Integer type) { this.setUserId(userId); this.setType(type); } public Integer getType() { return type; } public String getUserId() { return userId; } public void setType(Integer type) { this.type = type; } public void setUserId(String userId) { this.userId = userId; } // Auto-generated by Eclipse. @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((type == null) ? 0 : type.hashCode()); result = prime * result + ((userId == null) ? 0 : userId.hashCode()); return result; } // Auto-generated by Eclipse. @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Pk other = (Pk) obj; if (type != other.type) return false; if (userId == null) { if (other.userId != null) return false; } else if (!userId.equals(other.userId)) return false; return true; } }
这确实给了我一个不同的错误消息a NullPointerException,这向我暗示Spring Data JPA无法为构建查询findAllByUserId(...)。我改为对该查询方法进行了自定义实现:
NullPointerException
findAllByUserId(...)
public interface MyEntityRepository extends JpaRepository<MyEntity, Pk>, MyEntityRepositoryCustom { } public interface MyEntityRepositoryCustom { List<MyEntity> findAllByUserId(String userId); } public class MyEntityRepositoryImpl implements MyEntityRepositoryCustom { @PersistenceContext private EntityManager em; @Override public List<MyEntityRepositoryCustom> findAllByUserId(String userId) { return em .createQuery("select o from MyEntity o where o.userId=:userId", MyEntity.class).setParameter("userId", userId).getResultList(); } }
…而且, 它起作用了!