ManyToMany in sospensione senza chiavi composte
-
06-09-2019 - |
Domanda
ho a che fare con database legacy. E sto scrivendo unit test utilizzando POJO & hibernate e HSQLDB . E sto ottenendo il seguente errore:
17:09:03,946 ERROR SchemaExport:349 - Attempt to define a second primary key in statement
Diciamo che ho Post
e Tag
entità (e, naturalmente, i loro tavoli posts
e tags
). E c'è un altro tavolo per definire molti-a-molti tra Post
e Tag
chiamato post_tags
.
A causa post_tags
contiene alcune informazioni in più sulla relazione, come active
e deleted
colonne. Ho creato un'altra entità chiamata PostTag
per gestire questa situazione.
Per descrivere il mio problema qui sono le classi pseudo:
@Entity
@Table(name="post_tags")
public class PostTag {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@ManyToOne
private Post post;
@ManyToOne
private Tag tag;
// setters and getters
}
@Entity
@Table(name = "tags")
public class Tag {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@ManyToMany(mappedBy = "tags",cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Set<Post> posts;
// setters and getters
}
@Entity
@Table(name = "posts")
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@ManyToMany
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
@JoinTable(name = "post_tags", joinColumns = { @JoinColumn(name = "post_id") }, inverseJoinColumns = { @JoinColumn(name = "tag_id") })
private Set<Tag> tags;
// setters and getters
}
Quando guardo la dichiarazione che genera l'errore sembra Hibernate sta cercando di fare una chiave composta utilizzando PRIMARY KEY (post_id, tag_id)
, ed inoltre cerca di fare post_id
identity
.
Qualcuno può aiutarmi a risolvere il mio problema?
UPDATE:
Perché ho a che fare con un database legacy questo era solo un esempio per dimostrare il problema. Ma cercherò di tradurre la dichiarazione vera e propria seguendo l'esempio (PS: Non è ALTER TABLE
si tratta di un CREATE TABLE
):
create table post_tags (id integer not null, post integer, tag integer, post_id integer generated by default as identity (start with 1), tag_id integer not null, primary key (post_id, tag_id)
Soluzione
Il problema è il @Id nella PostTag
classe: dice ibernazione che si desidera un Colum identità generato. Allo stesso tempo, che stai dicendo "Voglio una chiave composta" con la mappatura del campo tags
nel Posts
classe.
Quale vuoi? Hibernate non può dire.
C'è un ottimo esempio a pagina 304 nel libro "Java Persistence con Hibernate". e 'su Google books .
Se non si desidera che la chiave composita, è necessario trattare la tabella di collegamento come oggetti reali e utilizzare PostTag
nel Posts
classe (cioè Set<PostTag> postTags
invece di Set<Tag> tags
)