Композитный ключ JPA с отображением дополнительных столбцов

Я уже несколько дней пытаюсь заставить составной ключ работать, просматривая множество примеров в Интернете, но все еще что-то упускаю, так как он не работает. С кодом, размещенным ниже, я в настоящее время испытываю следующую ошибку: Не удалось определить тип для: java.util.Set, для таблицы: USER_PROFILE, для столбцов: [org.hibernate.mapping.Column(userProfileDataFilter)].

Если я закомментирую UserProfileDataFilter из объекта UserProfile, все будет работать гладко с сохранением и удалением. Я переместил аннотации от переменных к получателям без удачи. Итак, я не уверен, что еще нужно сделать, поэтому я здесь умоляю о помощи.

Любое руководство через этот злой лабиринт аннотаций с благодарностью.

КЛАСС ПРОФИЛЯ ПОЛЬЗОВАТЕЛЯ:

@Entity
@Table(name="USER_PROFILE")
public class UserProfile extends UserProfileAbstract implements Serializable {

private static final long serialVersionUID = CommonDefines.SERIALVERSIONUID;

public Company company; 
private Set<UserProfileDataFilter> userProfileDataFilter = new HashSet<UserProfileDataFilter>(0);

public UserProfile(){super();}
public UserProfile(String ploginName, String ppassword, Date ppasswordExprDt, String pfirstName, String plastName,
        String pemail, UUID pcompanyId, Long pstatusId, UUID pcrtdId, Date pcrtdDt, UUID pmodId, Date pmodDt){

    super(ploginName, ppassword, ppasswordExprDt, pfirstName, plastName,
            pemail, pcompanyId, pstatusId, pcrtdId, pcrtdDt, pmodId, pmodDt);
}

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="COMPANY_ID",insertable=false,updatable=false,nullable=false)
public Company getCompany() {
    return company;
}
public void setCompany(Company company) {
    this.company = company;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.userProfile", cascade=CascadeType.ALL)
public Set<UserProfileDataFilter> getUserProfileDataFilter() {
    return userProfileDataFilter;
}
public void setUserProfileDataFilter(
        Set<UserProfileDataFilter> userProfileDataFilter) {
    this.userProfileDataFilter = userProfileDataFilter;
}

ФИЛЬТР ДАННЫХ ПРОФИЛЯ ПОЛЬЗОВАТЕЛЯ (КОМПОЗИЦИОННЫЙ КЛЮЧ):

@Entity
@Table(name="USER_PROFILE_DATA_FILTER")
@AssociationOverrides({
@AssociationOverride(name="pk.userProfile", joinColumns=@JoinColumn(name="USER_PROFILE_ID")),
@AssociationOverride(name="pk.dataFilter", joinColumns=@JoinColumn(name="DATA_FILTER_ID")) })
public class UserProfileDataFilter implements Serializable {

private static final long serialVersionUID = CommonDefines.SERIALVERSIONUID;
private UserProfileDataFilterPK pk = new UserProfileDataFilterPK();
private UUID crtdId;
private Date crtdDt;
private UUID modId;
private Date modDt;

@EmbeddedId
public UserProfileDataFilterPK getPk() {
    return pk;
}

public void setPk(UserProfileDataFilterPK pk) {
    this.pk = pk;
}

@Transient
public UserProfile getUserProfile() {
    return getPk().getUserProfile();
}

public void setUserProfile(UserProfile userProfile) {
    getPk().setUserProfile(userProfile);
}

@Transient
public DataFilter getDataFilter() {
    return getPk().getDataFilter();
}

public void setDataFilter(DataFilter dataFilter) {
    getPk().setDataFilter(dataFilter);
}


@Column(name="CRTD_ID", nullable=false)
public UUID getCrtdId() {
    return crtdId;
}

public void setCrtdId(UUID crtdId) {
    this.crtdId = crtdId;
}

@Column(name="CRTD_DT", nullable=false)
@Temporal(TemporalType.TIMESTAMP)
public Date getCrtdDt() {
    return crtdDt;
}

public void setCrtdDt(Date crtdDt) {
    this.crtdDt = crtdDt;
}

@Column(name="MOD_ID", nullable=false)
public UUID getModId() {
    return modId;
}

public void setModId(UUID modId) {
    this.modId = modId;
}

@Column(name="MOD_DT", nullable=false)
@Temporal(TemporalType.TIMESTAMP)
public Date getModDt() {
    return modDt;
}

public void setModDt(Date modDt) {
    this.modDt = modDt;
}
}

ФИЛЬТР ДАННЫХ ПРОФИЛЯ ПОЛЬЗОВАТЕЛЯ PK (Класс, используемый для определения ключа)

@Embeddable
public class UserProfileDataFilterPK implements Serializable {


private static final long serialVersionUID = CommonDefines.SERIALVERSIONUID;
private UserProfile userProfile;
private DataFilter  dataFilter;

@ManyToOne
public UserProfile getUserProfile() {
    return userProfile;
}
public void setUserProfile(UserProfile userProfile) {
    this.userProfile = userProfile;
}

@ManyToOne
public DataFilter getDataFilter() {
    return dataFilter;
}
public void setDataFilter(DataFilter dataFilter) {
    this.dataFilter = dataFilter;
}

public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

UserProfileDataFilterPK that = (UserProfileDataFilterPK) o;

if (userProfile != null ? !userProfile.equals(that.userProfile) : that.userProfile != null) return false;
if (dataFilter != null ? !dataFilter.equals(that.dataFilter) : that.dataFilter != null)
    return false;

return true;
}

public int hashCode() {
    int result;
    result = (userProfile != null ? userProfile.hashCode() : 0);
    result = 31 * result + (dataFilter != null ? dataFilter.hashCode() : 0);
    return result;
}
}

КЛАСС ФИЛЬТРА ДАННЫХ:

@Entity
@Table(name="DATA_FILTER")
public class DataFilter extends DataFilterAbstract {

private static final long serialVersionUID = CommonDefines.SERIALVERSIONUID;

@Transient
protected boolean selected;

@OneToMany(mappedBy="dataFilterId")
public Set<DataFilterDetail> dataFilterDetails;

public DataFilter(){super();}
public DataFilter(boolean pselected, String pname, String pdescription, boolean pActive, UUID pcrtdId, Date pcrtdDt, UUID pmodId, Date pmodDt){
    super(pname,pdescription,pActive, pcrtdId, pcrtdDt, pmodId, pmodDt);
    selected = pselected;
}

public boolean isSelected() {
    return selected;
}
public void setSelected(boolean selected) {
    this.selected = selected;
}
public Set<DataFilterDetail> getDataFilterDetails() {
    return dataFilterDetails;
}
public void setDataFilterDetails(Set<DataFilterDetail> dataFilterDetails) {
    this.dataFilterDetails = dataFilterDetails;
}

}

1 ответ

Решение

Иногда вы размещаете аннотации на полях, а иногда на аксессуарах (получателях). Всегда размещайте их на одном и том же месте в определенной иерархии классов.

IIRC, Hibernate рассматривает только аннотации, размещенные в том же месте, что и @Id (или же @EmbeddedId) аннотация. Так что если @Id на добытчике, и у вас есть @OneToMany на поле, @OneToMany аннотация будет игнорироваться.

Другие вопросы по тегам