【问题标题】:org.hibernate.InstantiationException: No default constructor for entity: com.domaine.AnomalieAckorg.hibernate.InstantiationException:没有实体的默认构造函数:com.domaine.AnomalieAck
【发布时间】:2019-04-04 09:23:48
【问题描述】:

我正在尝试将枚举值持久化到数据库中,但触发了实例化异常,这是我的映射:

@Entity
public class Anomalie {

    @Embedded
    private AnomalieAck ack = AnomalieAck.NON_ACQUITTEE;



    public Anomalie() {
    }
/*getters and setters*/
}

//AnomalieAck.java

public enum AnomalieAck {

    NON_ACQUITTEE(0),

    ACQUITTEE_APP1 (1),

    ACQUITTEE_APP2(2),

    /** Aacquittee en erreur. */
    ACQUITTEE_ERREUR(10),

    @Column(name = "ANO_ACK")
    private int ack = 0;

  private AnomalieAck() {

    }

  private AnomalieAck(final int value) {
    this.ack = value;
   }
  public int getValue() {
        return this.ack;
    }
  public void setAck(int ack) {
        this.ack = ack;
    }
}

我没有使用@Enumerated(EnumType.STRING)@Enumerated(EnumType.ORDINAL) 的原因是在数据库中字段 ANO_ACK 被声明为数字,并且有很多其他资源使用它值作为数字。

我已经检查了一切:no-args 构造函数已经定义,setter 方法已经实现。

我该怎么做才能让 Hibernate 实例化这个类?

【问题讨论】:

    标签: java hibernate enums hibernate-mapping instantiation


    【解决方案1】:

    不要嵌入枚举。

    您需要的是自定义转换器:

    转换器

    @Converter
    public class AnomalieAckConverter implements AttributeConverter<AnomalieAck , Integer> {
    
     @Override
     public String convertToDatabaseColumn(AnomalieAck  anomalieAck ) {
       return anomalieAck.getValue();
     }
    
     @Override
     public AnomalieAck convertToEntityAttribute(Integer ack) {
        retrun AnomalieAck.getByValue(ack);
     }
    
    }
    

    实体:

    @Column
    @Convert(converter = AnomalieAckConverter.class)
    private AnomalieAck ack;
    

    【讨论】:

    • 感谢您的回答,但我应该创建 AttributeConverter 接口吗?
    • 没有。这是 javax.persistence 包的一部分
    • 你可能需要在你的项目中添加 hibernate-jpa-2.1-api 依赖
    • 非常感谢您,但在数据库中,当 ack 的值被持久化时,它采用序数值而不是值本身。我可以做些什么来保存值而不是序数?它的工作方式就像我使用 (EnumType.Ordinal)
    • 在枚举中创建一个 getAck 方法并改用它
    【解决方案2】:

    枚举类

    public enum AnomalieAck {
    
        NON_ACQUITTEE(0),
    
        ACQUITTEE_APP1 (1),
    
        ACQUITTEE_APP2(2),
    
        /** Aacquittee en erreur. */
        ACQUITTEE_ERREUR(10),
    
    
        private int ack = 0;
    
      private AnomalieAck() {
    
        }
    
      private AnomalieAck(final int value) {
        this.ack = value;
       }
      public int getValue() {
            return this.ack;
        }
    
      public void setAck(int ack) {
            this.ack = ack;
        }
    
    public static AnomalieAck getByValue(int ackNumero) {
        for (final AnomalieAck ackitement : AnomalieAck.values()) {
    
            if (ackitement.getValue() == ackNumero) {
                return ackitement;
            }
        }
    
        return null;
    }
    
    }
    

    转换器:

    public class AnomalieAckConverter implements AttributeConverter<AnomalieAck, Integer> {
    
        /**
         * @param attribute
         * @return
         * @see javax.persistence.AttributeConverter#convertToDatabaseColumn(java.lang.Object)
         */
        @Override
        public Integer convertToDatabaseColumn(AnomalieAck anoAck) {
            // TODO Auto-generated method stub
            return anoAck.getValue();
        }
    
        /**
         * @param dbData
         * @return
         * @see javax.persistence.AttributeConverter#convertToEntityAttribute(java.lang.Object)
         */
        @Override
        public AnomalieAck convertToEntityAttribute(Integer ack) {
            // TODO Auto-generated method stub
            return AnomalieAck.getByValue(ack);
    
        }
    

    解决方案有效,但它保留序数值而不是其 int 值,getAck 是 getValue()

    【讨论】:

      猜你喜欢
      • 2017-10-20
      • 2018-01-10
      • 2019-08-08
      • 2020-02-07
      • 1970-01-01
      • 2014-10-16
      • 2015-03-19
      • 2023-03-20
      相关资源
      最近更新 更多