如何在 Spring JPA 存储库中使用构造函数映射 [英] How to use Constructor Mapping with Spring JPA Repositories

查看:37
本文介绍了如何在 Spring JPA 存储库中使用构造函数映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Spring 存储库,如下所示:

I have a Spring repository as follows:

import org.springframework.data.repository.Repository;
import org.springframework.stereotype.Component;

import com.test.domain.My;

@Component
public interface MyRepository extends Repository<My, String> {

    My findOne(String code);

    My findByName(String name);

}

实体类是:

import javax.persistence.ColumnResult;
import javax.persistence.ConstructorResult;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.SqlResultSetMapping;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

@JsonIgnoreProperties(ignoreUnknown=true)
@Entity
@Table(name="vMy", schema="test")
@SqlResultSetMapping(
    name="something",
    classes = {
        @ConstructorResult(targetClass = My.class,
            columns={
                @ColumnResult(name = "myCode", type = String.class),
                @ColumnResult(name = "myShortName", type = String.class)
             }
        )
    }
)
public class My {

    @Id
    @Column(name = "myCode")
    private final String code;

    @Column(name = "myShortName")
    private final String name;

   public My(String code, String name) {
        this.code = code;
        this.name = name;
   }

   @JsonCreator()
   public My(@JsonProperty("My_c") String code) {
       this.code = code;
       this.name = null;
  }

  public String getCode() {
      return code;
  }

  public String getName() {
      return name;
  }

  @Override
    public String toString() {
       return "{code: " + code + ", name: " + name + "}";
   }    
 } 

调用findOne或findByName时,报错如下:

When findOne or findByName is invoked, the following error is given:

   org.hibernate.InstantiationException: No default constructor for entity 

如何使用 Spring JPA 存储库而没有默认构造函数?我想保留实例字段、代码和名称,最终.

How can I use Spring JPA repository and not have a default constructor? I would like to keep the instance fields, code and name, final.

推荐答案

我将创建一个名为 MyDto 的单独类,它包含 JSON 内容,但不包含实体注释.也将其字段设为 final.

I would create a separate class called MyDto which has the JSON stuff, but not the Entity annotations. Make it's fields final as well.

那么你的存储库方法将是这样的:

Then your repository methods would be something like this:

@Query("SELECT new MyDto(m.code, m.name) FROM My m WHERE m.code = :code")
public MyDto findByCode(@Param("code") String code);

那样,您只使用 My Entity 类来为您提供到数据库列的映射,而不是创建 My 的实例.

That way, you are only using the My Entity class to give you the mapping to the database columns, not creating an instance of My.

另一种方法(此处详述) 是使用实体类本身作为 DTO.

Another approach (as detailed here) is to use the Entity class itself as the DTO.

因此您的查询方法可能如下所示:

So your query method could look like this:

@Query("SELECT new My(m.code, m.name) FROM My m WHERE m.code = :code")
public My findByCode(@Param("code") String code);

这样做的好处是不必创建单独的 DTO 类.

This has the advantage of not having to create a separate DTO class.

这篇关于如何在 Spring JPA 存储库中使用构造函数映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆