5

I'm using Hibernate and MySql and today I setted a composite primary key in one of my table, so below:

DefSelfLearning

DefSelfLearning

And this entity is OneToMany with SelfLearning:

enter image description here

This is my java entity:

@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;
    }

}

the class for the composite key:

    @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;
    }
}

and SelfLearning class:

@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;
    }
}

but when I create a defSelfLearning all work fine, but when I create a SelfLearning I receive MysqlDataTruncation exception:

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

This error is enough explined, but I don't find where is the problem, this is the code for SelfLearning creation:

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);

    }

Do you find where is the problem?Thanks

This is the first row of defSelfLearning and it's where the code fails

enter image description here

if I set manually this it works:

enter image description here

This is a screen of java debug of first code, that fails:

enter image description here

luca
  • 3,248
  • 10
  • 66
  • 145

3 Answers3

0

You try to insert a char which is longer than 15 in the column "id_parName"

Si mo
  • 969
  • 9
  • 24
  • If so it had been, defSelfLearning would have thrown exception before SelfLearning. The value of id_parName was 1008 and the table defSelfLearning has been correctly populated – luca Nov 19 '15 at 13:51
  • But the execption is clear. Please write a test, set the properties of your entities with some values and call save after that. If this test fails, post the code. It is difficult because we don't see the values you set to the properties of the entity – Si mo Nov 19 '15 at 13:54
  • 1
    Yes, I updated with two rows, the second was created through java code, like the first. Maybe I have found the error...SelfLearning wrong mapping the columns, id_parName= id_description, id_description= id_note and id_note=id_parName – luca Nov 19 '15 at 14:51
0

On your Entities, you have to choose between field and getter. And all the annotations should be on fields, or they should all be on getters, you can't mix both approaches (except if you use the @AccessType annotation). Hibernate / Jpa will pick up the used approch from the annotation on Id.

Change @Id on the first Embeddable entity to @EmbeddedId and make sure it is on the getter.

Rafik BELDI
  • 4,140
  • 4
  • 24
  • 38
  • I have removed '@Id' and '@EmbeddedId' from DefSelfLearning and I have added '@EmbeddedId' on public DefSelfLearningKeys getDefSelfLearningKeys() method but I still receive the error – luca Nov 19 '15 at 14:07
0

SelfLearning wrong mappings the columns, id_parName= id_description, id_description= id_note and id_note=id_parName, but why? So I read:

When the JoinColumns annotation is used, both the name and the referencedColumnName elements must be specified in each such JoinColumn annotation.

I have added this element so:

@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;
}

And it works

luca
  • 3,248
  • 10
  • 66
  • 145