弹簧数据jpa为多个连接表

时间:2016-07-15 22:29:01

标签: spring-data-jpa

我有两个表:ProductUsage和Learner。 ProductUsage有现场学习者,学习者有字段id和guid。现在我需要创建一个查询来提取其学习者guid在指定用户ID中的所有productUsage:

SQL:

select * from product_usage 
inner join learner
on product_usage.learner_id = learner.id
where 
learner.guid in ("1234", "2345")

域类:

@Data
@NoArgsConstructor
@Entity
@Table(name = "core_product_usage_increments")
public class ProductUsage {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "learner_id", nullable = false)
    private Learner learner;

    @ManyToOne
    @JoinColumn(name = "learning_language_id", nullable = false)
    private Language language;
}

@Data
@NoArgsConstructor
@Entity
@Table(name = "learners")
public class Learner {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(name = "user_guid", nullable = false, unique = true)
    private String guid;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;
}

和存储库类:

@Repository
public interface ProductUsageRepository extends CrudRepository<ProductUsage, Integer> {
    @Query("SELECT p FROM ProductUsage p WHERE p.learnerGuid = :learnerGuid")
    List<ProductUsage> findByLearnerGuid(String learnerGuid);
}

调用存储库的客户端类

@Component
public class MyClient {
    @Autowired
    private ProductUsageRepository repository;

    public MyClient(ProductUsageRepository repository) {
        this.repository = repository;
    }

    public List<ProductUsage> getProductUageByLeanrerGuid(String learnerGuid) {
        return repository.findByLearnerGuid(learnerGuid);
    }
}

和我的测试:

@Test
    public void testClient() throws Exception {
        MyClient client = new MyClient(repository);
        List<ProductUsage> results = client.getProductUageByLeanrerGuid("1234");
        assertNotNull(result);
    }

它失败了:

Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: learnerGuid of: com.acme.domain.spectrum.ProductUsage [SELECT p FROM com.acme.domain.spectrum.ProductUsage p WHERE p.learnerGuid = :learnerGuid]
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1364)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
    at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:294)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)

它无法识别ProductUsage中的'learnerGuid'字段,但实际上是在Learner类中定义的。如何执行连接多个表的查询?

2 个答案:

答案 0 :(得分:2)

ProductUsage没有learnerGuid属性,只有learner。尝试

@Query("SELECT p FROM ProductUsage p WHERE p.learner.guid = :learnerGuid")

如果这不起作用,我还有另一个提示:

@Query("SELECT p FROM ProductUsage p join p.Learner l WHERE l.guid = :learnerGuid")

答案 1 :(得分:0)

您没有像以前那样使用@query

@Query("SELECT p FROM ProductUsage p WHERE p.learnerGuid = :learnerGuid")
    List<ProductUsage> findByLearnerGuid(String learnerGuid);

Spring JPA框架可以通过方法名称本身来构建查询。试试这个

List<ProductUsage> findByLearnerGuid(String learnerGuid);

List<ProductUsage> findByLearner_guid(String learnerGuid);

当您与ProductUsage中的Learner有关系时,findBy方法可以遍历相关表及其字段。 “ _”通过加入guid =?

的Learner表,为框架提供了明确的查询指示。

否则,框架尝试以下两种组合:

where learnerGuid=?
join learner where guid=?