【问题标题】:Composite primary Key and Data truncation error复合主键和数据截断错误
【发布时间】:2016-02-21 16:31:19
【问题描述】:

我正在使用 Hibernate 和 MySql,今天我在我的一张表中设置了一个复合主键,如下所示:

自学

而且这个实体是 OneToMany 和 SelfLearning:

这是我的 java 实体:

@Entity
@Table(name = "defselflearning", catalog = "ats")
public class DefSelfLearning implements java.io.Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private DefSelfLearningKeys defSelfLearningKeys;
    private Ecu ecu;
    private String excelColumn;
    @JsonIgnore
    private Set<SelfLearning> selfLearnings = new HashSet<SelfLearning>(0);

    public DefSelfLearning() {
    }

    public DefSelfLearning(DefSelfLearningKeys defSelfLearningKeys, Ecu ecu) {
        this.defSelfLearningKeys = defSelfLearningKeys;
        this.ecu = ecu;
    }

    public DefSelfLearning(Ecu ecu, DefSelfLearningKeys defSelfLearningKeys, String excelColumn, Set<SelfLearning> selfLearnings) {
        this.ecu = ecu;
        this.defSelfLearningKeys = defSelfLearningKeys; 
        this.excelColumn = excelColumn;
        this.selfLearnings = selfLearnings;
    }

    @Id
    public DefSelfLearningKeys getDefSelfLearningKeys() {
        return this.defSelfLearningKeys;
    }

    public void setDefSelfLearningKeys(DefSelfLearningKeys defSelfLearningKeys) {
        this.defSelfLearningKeys = defSelfLearningKeys;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_ecu", nullable = false)
    public Ecu getEcu() {
        return this.ecu;
    }

    public void setEcu(Ecu ecu) {
        this.ecu = ecu;
    }

    @Column(name = "excelColumn", length = 2)
    public String getExcelColumn() {
        return this.excelColumn;
    }

    public void setExcelColumn(String excelColumn) {
        this.excelColumn = excelColumn;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "defSelfLearning")
    public Set<SelfLearning> getSelfLearnings() {
        return this.selfLearnings;
    }

    public void setSelfLearnings(Set<SelfLearning> selfLearnings) {
        this.selfLearnings = selfLearnings;
    }

}

复合键的类:

    @Embeddable
public class DefSelfLearningKeys implements Serializable {
    private static final long serialVersionUID = 1L;
    protected String parName;
    protected String description;
    protected String note;

    public DefSelfLearningKeys() {}

    public DefSelfLearningKeys(String parName, String description, String note) {
        this.parName = parName;
        this.description = description;
        this.note = note;
    }

    @Column(name = "parName", nullable = false, length = 15)
    public String getParName() {
        return this.parName;
    }

    public void setParName(String parName) {
        this.parName = parName;
    }

    @Column(name = "description", nullable = false, length = 100)
    public String getDescription() {
        return this.description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Column(name = "note", nullable = false, length = 100)
    public String getNote() {
        return this.note;
    }

    public void setNote(String note) {
        this.note = note;
    }
}

和自学课程:

@Entity
@Table(name = "selflearning", catalog = "ats")
public class SelfLearning implements java.io.Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private int idSelfLearning;
    private Acquisition acquisition;
    private DefSelfLearning defSelfLearning;
    private String value;

    public SelfLearning() {
    }

    public SelfLearning(int idSelfLearning, Acquisition acquisition, DefSelfLearning defSelfLearning) {
        this.idSelfLearning = idSelfLearning;
        this.acquisition = acquisition;
        this.defSelfLearning = defSelfLearning;
    }

    public SelfLearning(int idSelfLearning, Acquisition acquisition, DefSelfLearning defSelfLearning, String value) {
        this.idSelfLearning = idSelfLearning;
        this.acquisition = acquisition;
        this.defSelfLearning = defSelfLearning;
        this.value = value;
    }

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id_selfLearning", unique = true, nullable = false)
    public int getIdSelfLearning() {
        return this.idSelfLearning;
    }

    public void setIdSelfLearning(int idSelfLearning) {
        this.idSelfLearning = idSelfLearning;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_acquisition", nullable = false)
    public Acquisition getAcquisition() {
        return this.acquisition;
    }

    public void setAcquisition(Acquisition acquisition) {
        this.acquisition = acquisition;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns({
          @JoinColumn(name = "id_parName", nullable = false),
          @JoinColumn(name = "id_description", nullable = false),
          @JoinColumn(name = "id_note", nullable = false)
        })
    public DefSelfLearning getDefSelfLearning() {
        return this.defSelfLearning;
    }

    public void setDefSelfLearning(DefSelfLearning defSelfLearning) {
        this.defSelfLearning = defSelfLearning;
    }

    @Column(name = "value")
    public String getValue() {
        return this.value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

但是当我创建一个 defSelfLearning 时一切正常,但是当我创建一个 SelfLearning 时我收到 MysqlDataTruncation 异常:

Caused by: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'id_parName' at row 1

这个错误已经足够解释了,但是我没有发现问题出在哪里,这是SelfLearning创建的代码:

for (DefSelfLearning defSelfLearning:defSelfLearningList){
        SelfLearning selfLearning=new SelfLearning();
        String key = defSelfLearning.getExcelColumn()+index;
        String value = actualRowValues.get(key);
        selfLearning.setAcquisition(findByCarAndExcelRow(carServices.findById(acquisitionForm.getCar()), index));
        selfLearning.setDefSelfLearning(defSelfLearning);
        selfLearning.setValue(value);
        System.out.println(selfLearning.getDefSelfLearning().getDefSelfLearningKeys().getParName());
        selfLearningServices.create(selfLearning);

    }

你找到问题出在哪里了吗?谢谢

这是 defSelfLearning 的第一行,也是代码失败的地方

如果我手动设置它会起作用:

这是第一个代码的java调试屏幕,失败了:

【问题讨论】:

    标签: java mysql hibernate truncate composite-primary-key


    【解决方案1】:

    您尝试在“id_parName”列中插入一个长度超过 15 的字符

    【讨论】:

    • 如果是这样,defSelfLearning 会在 SelfLearning 之前抛出异常。 id_parName 的值为 1008,并且表 defSelfLearning 已正确填充
    • 但是执行很清楚。请编写一个测试,使用一些值设置实体的属性,然后调用 save 。如果此测试失败,请发布代码。这很困难,因为我们看不到您为实体属性设置的值
    • 是的,我更新了两行,第二行是通过 java 代码创建的,和第一行一样。也许我发现了错误...SelfLearning 映射列错误,id_parName= id_description, id_description= id_note 和 id_note=id_parName
    【解决方案2】:

    在您的实体上,您必须在字段和吸气剂之间进行选择。并且所有注释都应该在字段上,或者它们都应该在 getter 上,您不能混合使用两种方法(除非您使用 @AccessType 注释)。 Hibernate / Jpa 将从 Id 上的注释中获取使用的方法。

    将第一个 Embeddable 实体上的 @Id 更改为 @EmbeddedId 并确保它位于 getter 上。

    【讨论】:

    • 我已经从 DefSelfLearning 中删除了 '@Id' 和 '@EmbeddedId' 并且我在公共 DefSelfLearningKeys getDefSelfLearningKeys() 方法中添加了 '@EmbeddedId' 但我仍然收到错误
    【解决方案3】:

    SelfLearning 错误映射列,id_parName= id_description,id_description= id_note 和 id_note=id_parName,但是为什么? 于是我读了:

    当使用 JoinColumns 注释时,名称和 必须在每个此类中指定 referencedColumnName 元素 JoinColumn 注释。

    我已经添加了这个元素:

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns({
          @JoinColumn(name = "id_parName", referencedColumnName="parName", nullable = false),
          @JoinColumn(name = "id_description", referencedColumnName="description", nullable = false),
          @JoinColumn(name = "id_note", referencedColumnName="note", nullable = false)
        })
    public DefSelfLearning getDefSelfLearning() {
        return this.defSelfLearning;
    }
    

    它有效

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-15
      • 2020-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多