Ein Zu Viele und Doppelte Eintrag
Verwende ich JPA->Hibernate. PlayFramework. Ich will eine Beziehung zu haben.
Category - 1:n -> Tag
Jede Kategorie kann beliebig viele tags, aber tags nicht zu kennen.
So, ich mag das:
@Entity public class Category ... { @OneToMany public List<Tag> tags = new LinkedList<Tag>(); }
Habe ich test:
@Test
public void playWithTags() {
Tag tag1 = new Tag("tag1").save(); //managed by playframework
Category cat1 = new Category("cat1");
cat1.tags.add(tag1);
cat1.save();
//check if tag1 and cat1 were saved
assertEquals(1, Tag.count());
assertEquals(1, Category.count());
Category cat2 = new Category("cat2");
cat2.tags.add(tag1);
cat2.save();
}
Ist das Ergebnis:
16:18:01,555 ERROR ~ Duplicate entry '1' for key 'tags_id'
16:18:01,555 ERROR ~ Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelp
....
java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.sql.BatchUpdateException: Duplicate entry '1' for key 'tags_id'
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2020)
Scheint es, dass cat2.save() versuchen, mehr zu tun, dann sollte es
Falls, wenn die Verwendung der merge() anstelle von save() funktioniert es gut:
cat2.merge();
ABER WARUM?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Habe ich das problem behoben. Das problem war, dass ich NICHT, DASS Anmerkungen. Also ich habe gerade @OneToMany an @ManyToMany-und voilà - Keine Einschränkungen mehr.
Aber wenn Sie sagen, über die OneToMany dann scheint es, gab es eine unique-Einschränkung auf Datenbank-Ebene, die uns daran gehindert zu setzen, nicht eindeutige Werte zu tags_id. Daher konnten wir nicht denselben tag, um Eine Kategorie. I. e. er wollte Eine Kategorie für Viele tags, aber wenn die tags wurden bereits "benutzt" - no way.. ich versuchte, unique=true/false in der @JoinTable -> @JoinColumn - aber es hilft nicht. Für mich ist es immer noch seltsam, aber zumindest aktuelle problem war behoben.
Du bist die Vermischung der beiden Konzepte: Primäre Schlüssel und ausländischen - Taste.
Kann es nur eine PK, aber FK nur bedeutet "es muss ein element mit dieser ID in einigen anderen Tabelle". FK nicht einschränken Einzigartigkeit.
[EDIT] Dein problem ist, dass Sie mischen Entitäten. Wie bist du auf die
tag1
die zurückgegeben wirdsave()
?Diese Person muss etwas sein, was Sie bekommen aus dem Ruhezustand, nicht das Ergebnis von
new
. Auch wenn es wahnsinnig, Sie müssen dies tun, insave()
:Diese Weise erhalten Sie eine Entität, die verwaltet wird von Hibernate. Nur, wenn die Entität verwaltet Hibernate, Hibernate weiß, wenn es um speichern Sie die Entität, und wenn es bereits gespeichert wurde.
Also, wenn Sie
cat2.tags.add(tag1);
in deinem Beispiel oben, Hibernate denkt "oh, ich weiß nichts über diesen tag, es muss eine neue sein".Und versucht zu retten, den tag wieder.
merge()
löst das problem: Es legt die Person zu der Sitzung.