2015-01-21 6 views
2

У меня есть приложение с составной таблицей, содержащей один дополнительный столбец. Все работает отлично, пока мы не добавим Hibernate Envers (@Audited).Композитная таблица с Hibernate Envers

org.hibernate.MappingException: Невозможно прочитать карту с помощью атрибута для responseDomainCodes в no.pack.response.ResponseDomainCode

Я рад предоставить более подробную информацию, если это необходимо, однако, при этом Я не уверен, что будет актуальным.

Таблицы выглядят так, и это довольно стандартная составная таблица клавиш с одним дополнительным столбцом.

Схема базы данных

+-----------+---------+ 
| CODE | TYPE | 
+-----------+---------+ 
| category | VARCHAR | 
| code  | VARCHAR | 
+-----------+---------+ 
      | 
      | 
+----------------------+---------+ 
| RESPONSE_DOMAIN_CODE | TYPE | 
+----------------------+---------+ 
| response_domain_id | KEY  | 
| code_id    | KEY  | 
| rank     | VARCHAR | 
+----------------------+---------+ 
      | 
      | 
+--------------------+------+ 
| RESPONSE_DOMAIN | TYPE | 
+--------------------+------+ 
| response_domain_id | PK | 
| response_kind_id | FK | 
+--------------------+------+ 

ResponseDomain.java

@Entity 
@Table(name = "responseDomain") 
public class ResponseDomain implements Serializable { 

    @Id 
    @Column(name = "responseDomain_id") 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @ManyToOne 
    @JoinColumn(name = "respons_kind_id") 
    private ResponseKind responseKind; 

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.responseDomain", cascade = CascadeType.ALL) 
    private Set<ResponseDomainCode> responseDomainCodes = new HashSet<>(); 

//Omitted rest. 
} 

Code.java

@Entity 
@Table(name = "code") 
public class Code implements Serializable { 

    @Id 
    @Column(name = "code_id") 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String category; 

    private String code; 

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.code", cascade = CascadeType.ALL) 
    private Set<ResponseDomainCode> responseDomainCodes = new HashSet<>(); 

    //Omitted rest 
} 

ResponseDomainCode.java

@Entity 
@Table(name = "responseDomain_code") 
@AssociationOverrides(value = { 
     @AssociationOverride(name = "pk.responseDomain", 
       joinColumns = @JoinColumn(name = "responseDomain_id")), 
     @AssociationOverride(name = "pk.code", 
       joinColumns = @JoinColumn(name = "code_id")) 
}) 
public class ResponseDomainCode implements Serializable { 

    @EmbeddedId 
    private ResponseDomainCodeId pk = new ResponseDomainCodeId(); 

    @Column(name = "rank") 
    private String rank; 

    public ResponseDomainCodeId getPk() { 
     return pk; 
    } 

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

    public String getRank() { 
     return rank; 
    } 

    public void setRank(String rank) { 
     this.rank = rank; 
    } 

    @Transient 
    public ResponseDomain getResponseDomain() { 
     return getPk().getResponseDomain(); 
    } 

    public void setResponseDomain(ResponseDomain responseDomain) { 
     this.getPk().setResponseDomain(responseDomain); 
    } 

    @Transient 
    public Code getCode() { 
     return getPk().getCode(); 
    } 

    public void setCode(Code code) { 
     this.getPk().setCode(code); 
    } 

    //Omitted rest 
} 

ResponseDomainCodeId.java

@Embeddable 
public class ResponseDomainCodeId implements Serializable { 

    @ManyToOne 
    private ResponseDomain responseDomain; 

    @ManyToOne 
    private Code code; 

    public ResponseDomainCodeId() { 
    } 

    public ResponseDomain getResponseDomain() { 
     return responseDomain; 
    } 

    public void setResponseDomain(ResponseDomain responseDomain) { 
     this.responseDomain = responseDomain; 
    } 

    public Code getCode() { 
     return code; 
    } 

    public void setCode(Code code) { 
     this.code = code; 
    } 

    //Omitted rest 
} 
+0

Я думаю, что Envers теряется из составного первичного ключа - вероятно, ошибка. – adamw

+0

Благодарим за быстрый ответ. Есть ли у вас идеи о том, как обойти эту ошибку? Я могу добавить, что если я удалю отображение в ResponseDomain и Code, оно работает просто отлично, но отношения становятся странными. Он также «работает», если я перемещаю @ManyToOne из ResponseDomainCodeId.java в ResponseDomainCode.java. – scav

+0

А у вас есть отношение во встроенном id. Я почти уверен, что пока не поддерживается. Не уверен, есть ли какие-либо обходные пути ... кроме наличия «нормального» идентификатора, как долго. – adamw

ответ

3

С помощью @adamw мне удалось решить эту проблему, изменив свое отображение.

Вместо использования составного ключа была создана таблица со своим уникальным идентификатором.

+----------------------+------------+ 
| RESPONSE_DOMAIN_CODE | TYPE | 
+----------------------+------------+ 
| id     | PK(BIGINT) | 
| response_domain_id | BIGINT  | 
| code_id    | BIGINT  | 
| rank     | VARCHAR | 
+----------------------+------------+ 

Теперь вместо того, чтобы использовать @Embeddable и @EmbeddedId У меня есть @ManyToOne и @OneToMany аннотацию по обе стороны, и запрос, основанный на ResponseDomain.

Это позволяет контролировать аудит полной версии с использованием Hibernate Envers также в таких отношениях.

Я надеюсь, что это будет полезно для кого-то в какой-то момент.

Смежные вопросы