当前位置: 首页 > 知识库问答 >
问题:

如何在Spring JPA存储库中使用构造函数映射

山阳辉
2023-03-14

我有一个Spring仓库如下:

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时,会给出以下错误:

   org.hibernate.InstantiationException: No default constructor for entity 

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

共有1个答案

卫俊力
2023-03-14

我将创建一个名为MyDto的单独类,它包含JSON内容,但不包含实体注释。让它成为最终的。

那么您的存储库方法应该是这样的:

@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的实例。

编辑:另一种方法(如这里所详述的)是使用实体类本身作为DTO。

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

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

这样做的优点是不必创建单独的DTO类。

 类似资料:
  • 我正在尝试在Spring Data Repository的nativeQuery中使用oracle的NVL函数。 当我在参数中传递值时,它会抛出异常如果我在“programId”中传递有效值,那么它工作正常。 例外情况:

  • 问题内容: 如何使用call_user_func_array调用类的构造函数 这是不可能的: 因为如果构造函数具有参数,则 新的 将失败。 约束:我不控制必须实例化的类,也不能修改它们。 不要问我为什么要做这个疯狂的事情,这是一个疯狂的考验。 问题答案: 您可以像这样使用反射: 从PHP 5.6.0起,也可以将运算符用于此目的。

  • 问题内容: 所有, 我正在尝试在一些古老的Java代码中进行一些单元测试(无接口,无抽象等)。 这是一个使用ServletContext的servlet(我假设它是由Tomcat设置的),并且它的数据库信息在web.xml / context.xml文件中设置。现在,我已经弄清楚了如何制作Fake ServletContext,但是代码已经 遍布整个地方(因此替换它是不可行的)。我需要找到一种方法

  • 问题内容: 如果我有一个像这样的构造函数: 然后,我如何在与构造函数相同的类中的方法中使用变量c和d,因为尝试仅在方法中使用变量名似乎不起作用? 问题答案: 实际上,您的代码将无法编译- 无效。 我认为您的意思是:- 。 然后我如何在与构造函数相同的类中的方法中使用变量c和d 您不能这样做,因为您已将它们声明为局部变量,其范围在构造函数结束执行时终止。 您应该将它们声明为实例变量。

  • 但是,VSC告诉我“构造函数调用必须是构造函数中的第一条语句”。我怎样才能克服这个问题?

  • 问题内容: 我正在尝试第一次使用PowerMockito模拟类构造函数,但是它不起作用。我当前的代码是: 测试失败,因为返回的值为“ Fail”。我的问题在哪里? 问题答案: Okey,找到答案了,您需要致电 代替