HIbernate + JPA Composite Key проблема: создание select sql с неправильными столбцами - PullRequest
2 голосов
/ 10 сентября 2010

Вот мои примеры кодов.

Класс PrimaryKey:

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-запроса следующим образом:

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

некоторые поля повторяются, а имена полей похожи на имена свойств, что означает не имя столбца БД.

1 Ответ

1 голос
/ 10 сентября 2010

Вики-книга JPA довольно хорошо объясняет, как отобразить такого рода отношения (a

JPA 1.0 требует, чтобы все @Id отображения будут основными отображениями, так что если ваш Идентификатор исходит из столбца внешнего ключа через OneToOne или ManyToOne сопоставление, вы также должны определить Basic @Id сопоставление для внешнего ключа колонка. Причина этого отчасти что идентификатор должен быть простым объектом для целей идентификации и кэширования, и для использования в IdClass или EntityManager find() API.

Потому что теперь у вас есть два отображения для тот же столбец внешнего ключа вы должны определить, какой из них будет написан база данных (это должно быть Basic один), так что OneToOne или ManyToOne внешний ключ должен быть определен как только для чтения. Это делается через установка атрибутов JoinColumn insertable и updatable до false, или используя @PrimaryKeyJoinColumn вместо @JoinColumn.

Побочный эффект наличия двух отображений для того же столбца, что вы сейчас должны держать два в синхронизации. Это как правило, делается с помощью набора метод для атрибута OneToOne также установите базовое значение атрибута на идентификатор целевого объекта. Это может стать очень сложно, если цель первичный ключ объекта является GeneratedValue, в этом случае вы должны убедитесь, что идентификатор целевого объекта имеет был назначен до того, как связать два объекты.

Поэтому попробуйте следующее:

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

    ...
}

Ресурс

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...