HIbernate + JPA Composite Key问题:生成带有错误列的select sql

时间:2010-09-10 09:58:27

标签: java hibernate orm jpa

这是我的示例代码。

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

使用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生成如下:

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 ...

某些字段正在重复,字段名称就像属性名称意味着不是db列名。

1 个答案:

答案 0 :(得分:1)

JPA维基书很好地解释了如何映射这种关系(

  

JPA 1.0要求所有@Id   映射是基本映射,所以如果你的   Id来自外键列   通过OneToOneManyToOne   映射,您还必须定义Basic   外键的@Id映射   柱。其原因部分在于此   Id必须是一个简单的对象   用于身份和缓存目的,以及   用于IdClass或。{   EntityManager find() API。

     

因为你现在有两个映射   你必须使用相同的外键列   定义将写入哪一个   数据库(必须是Basic   一),所以OneToOneManyToOne   必须定义外键   只读。这是通过完成的   设置JoinColumn属性   insertableupdatablefalse,或   使用@PrimaryKeyJoinColumn   而不是@JoinColumn

     

具有两个映射的副作用   对于同一列,就是你现在   必须保持两者同步。这是   通常通过设置完成   OneToOne属性的方法也是   将Basic属性值设置为   目标对象的id。这可以成为   如果目标非常复杂   对象的主键是a   GeneratedValue,在这种情况下你必须   确保目标对象的id具有   在将两者联系起来之前已经分配   对象。

请尝试以下方法:

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

    ...
}

资源