开发者

HIbernate+JPA Composite Key problem: generating select sql with wrong columns

Here is my sample codes.

PrimaryKey Class:

public class ReplAreaElemDataCompositeKey implements Serializable{

private static final long serialVersionUID = 1L;    
private int imageElementID; 
private int variableID;

public ReplAreaElemDataCompositeKey() {
    super();
}

/**
 * @param imageElementID
 * @param variableID
 */
public ReplAreaElemDataCompositeKey(int imageElementID, int variableID) {
    super();
    this.imageElementID = imageElementID;
    this.variableID = variableID;
}

/**
 * Method to getImageElementID
 *
 * @return the imageElementID
 */

public int getImageElementID() {
    return imageElementID;
}

/**
 * Method to setImageElementID
 *
 * @param imageElementID the imageElementID to set
 */
public void setImageElementID(int imageElementID) {
    this.imageElementID = imageElementID;
}

/**
 * Method to getVariableID
 *
 * @return the variableID
 */

public int getVariableID() {
    return variableID;
}

/**
 * Method to setVariableID
 *
 * @param variableID the variableID to set
 */
public void setVariableID(开发者_Go百科int variableID) {
    this.variableID = variableID;
}

@Override
public int hashCode() {
    int hash = 0;
    hash += (int) imageElementID;
    hash += (int) variableID;
    return hash;
}

@Override
public boolean equals(Object object) {
    if (!(object instanceof ReplAreaElemDataCompositeKey)) {
        return false;
    }
    ReplAreaElemDataCompositeKey other = (ReplAreaElemDataCompositeKey) object;
    if (this.imageElementID != other.getImageElementID()) {
        return false;
    }
    if (this.variableID != other.getVariableID()) {
        return false;
    }

    return true;
}
}

class using PrimaryKey

@Entity
@IdClass(ReplAreaElemDataCompositeKey.class)
public class ReplAreaElemDataEntity {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "IMAGE_ELEM_NBR", insertable=false, updatable=false)
    private int imageElementID;

    @Id
    @Column(name = "REPL_VAR_NBR", insertable=false, updatable=false)
    private int variableID;

    @ManyToOne
    @JoinColumn(name="IMAGE_ELEM_NBR")
    private ImageElementEntity imageElementEntity;

    @ManyToOne
    @JoinColumn(name="REPL_VAR_NBR")
    private ReplVariableEntity replVariableEntity;

    @Lob
    @Column(name = "REPL_AREA_DATA")
    private String variableData;

    /**
     * Method to getImageElementID
     *
     * @return the imageElementID
     */

    public int getImageElementID() {
        return imageElementID;
    }

    /**
     * Method to setImageElementID
     *
     * @param imageElementID the imageElementID to set
     */
    public void setImageElementID(int imageElementID) {
        this.imageElementID = imageElementID;
    }

    /**
     * Method to getVariableID
     *
     * @return the variableID
     */

    public int getVariableID() {
        return variableID;
    }

    /**
     * Method to setVariableID
     *
     * @param variableID the variableID to set
     */
    public void setVariableID(int variableID) {
        this.variableID = variableID;
    }

    /**
     * Method to getImageElementEntity
     *
     * @return the imageElementEntity
     */

    public ImageElementEntity getImageElementEntity() {
        return imageElementEntity;
    }

    /**
     * Method to setImageElementEntity
     *
     * @param imageElementEntity the imageElementEntity to set
     */
    public void setImageElementEntity(ImageElementEntity imageElementEntity) {
        this.imageElementEntity = imageElementEntity;
    }

    /**
     * Method to getReplVariableEntity
     *
     * @return the replVariableEntity
     */

    public ReplVariableEntity getReplVariableEntity() {
        return replVariableEntity;
    }

    /**
     * Method to setReplVariableEntity
     *
     * @param replVariableEntity the replVariableEntity to set
     */
    public void setReplVariableEntity(ReplVariableEntity replVariableEntity) {
        this.replVariableEntity = replVariableEntity;
    }

    /**
     * Method to getVariableData
     *
     * @return the variableData
     */

    public String getVariableData() {
        return variableData;
    }

    /**
     * Method to setVariableData
     *
     * @param variableData the variableData to set
     */
    public void setVariableData(String variableData) {
        this.variableData = variableData;
    }   
}

SQL Query generating like this:

SELECT replareael0_.IMAGE_ELEM_NBR AS IMAGE4_2_,
  replareael0_.imageElementID      AS imageEle1_2_,
  replareael0_.variableID          AS variableID2_,
  replareael0_.imageElementID      AS imageEle1_2_1_,
  replareael0_.variableID          AS variableID2_1_,
  replareael0_.IMAGE_ELEM_NBR      AS IMAGE4_2_1_
 ...
 ...
from ...

some fields are repeating and field names are like property names means not db column name.


The JPA wiki book explains pretty well how to map this kind of relation (a

JPA 1.0 requires that all @Id mappings be Basic mappings, so if your Id comes from a foreign key column through a OneToOne or ManyToOne mapping, you must also define a Basic @Id mapping for the foreign key column. The reason for this is in part that the Id must be a simple object for identity and caching purposes, and for use in the IdClass or the EntityManager find() API.

Because you now have two mappings for the same foreign key column you must define which one will be written to the database (it must be the Basic one), so the OneToOne or ManyToOne foreign key must be defined to be read-only. This is done through setting the JoinColumn attributes insertable and updatable to false, or by using the @PrimaryKeyJoinColumn instead of the @JoinColumn.

A side effect of having two mappings for the same column is that you now have to keep the two in synch. This is typically done through having the set method for the OneToOne attribute also set the Basic attribute value to the target object's id. This can become very complicated if the target object's primary key is a GeneratedValue, in this case you must ensure that the target object's id has been assigned before relating the two objects.

So try the following instead:

@Entity
@IdClass(ReplAreaElemDataCompositeKey.class)
public class ReplAreaElemDataEntity {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "IMAGE_ELEM_NBR")
    private int imageElementID;

    @Id
    @Column(name = "REPL_VAR_NBR")
    private int variableID;

    @ManyToOne
    @PrimaryKeyJoinColumn(name="IMAGE_ELEM_NBR")
    private ImageElementEntity imageElementEntity;

    @ManyToOne
    @PrimaryKeyJoinColumn(name="REPL_VAR_NBR")
    private ReplVariableEntity replVariableEntity;

    @Lob
    @Column(name = "REPL_AREA_DATA")
    private String variableData;

    ...
}

Resource

  • JPA Wiki Book
    • Primary Keys through OneToOne Relationships
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜