2017-02-12 2 views
0

Modellierung meiner SpringBoot-Anwendung mit Hibernate und PostgreSQL als Datenbank. Brauchen Sie Hilfe, um Beziehung ManyToMany richtig herzustellen. Klasse News:ManyToMany-Beziehung Hibernate

@Entity(name = "news") 
public class News implements Serializable { 
    private Long id; 
    private Date date; 
    private String text; 
    private String author; 
    private Set<HashTag> hashTags = new HashSet<HashTag>(0); 
    private byte[] image; 

    public News() { 
    } 

    public News(Date date, String text, String author, Set<HashTag> hashTags, byte[] image) { 
     this.date = date; 
     this.text = text; 
     this.author = author; 
     this.hashTags = hashTags; 
     this.image = image; 
    } 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "news_id") 
    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    @Temporal(TemporalType.DATE) 
    @DateTimeFormat(pattern = "DD/MM/YYYY") 
    public Date getDate() { 
     return date; 
    } 

    public void setDate(Date date) { 
     this.date = date; 
    } 

    @Lob 
    @Type(type = "org.hibernate.type.TextType") 
    public String getText() { 
     return text; 
    } 

    public void setText(String text) { 
     this.text = text; 
    } 

    public String getAuthor() { 
     return author; 
    } 

    public void setAuthor(String author) { 
     this.author = author; 
    } 

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) 
    @JoinTable(name = "news_hashTag", 
      joinColumns = @JoinColumn(name = "news_id"), 
      inverseJoinColumns = @JoinColumn(name = "hashtag_id")) 
    public Set<HashTag> getHashTags() { 
     return hashTags; 
    } 

    public void setHashTags(Set<HashTag> hashTags) { 
     this.hashTags = hashTags; 
    } 

    @Lob 
    public byte[] getImage() { 
     return image; 
    } 

    public void setImage(byte[] image) { 
     this.image = image; 
    } 

Und Klasse Hashtag:

@Entity(name = "hashTag") 
public class HashTag implements Serializable { 
    private Long id; 

    private String name; 
    private String description; 
    private Set<News> news = new HashSet<News>(0); 

    public HashTag() { 
    } 

    public HashTag(String name, String description) { 
     this.name = name; 
     this.description = description; 
    } 

    @Id 
    @GeneratedValue (strategy = GenerationType.IDENTITY) 
    @Column(name = "hashtag_id") 
    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @ManyToMany(cascade = CascadeType.ALL, mappedBy = "hashTags") 
    public Set<News> getNews() { 
     return news; 
    } 

    public void setNews(Set<News> news) { 
     this.news = news; 
    } 

Wenn ich Nachrichten versuchen, speichern wie folgt aus:

Set<HashTag> hashTags = new HashSet<>(); 
hashTags.add(new HashTag("HashTag 1"); 
hashTags.add(new HashTag("HashTag 2"); 

News news = new News(); 
news.text = "Some text"; 
news.author = "Some author"; 
news.date = new Date(); 
news.hashTags = hashTags; 

newsService.save(news); 

Ich erhalte Fehler:

ERROR: null value in column "news_id" violates not-null constraint

+0

Sie könnten versuchen 'hashTags.forEach (h -> setNews (news));' - mit anderen Worten, geben Sie den HashTags einen Verweis auf ihr Nachrichtenobjekt, das dann die news_id-Spalte füllt. –

+0

Versucht, nichts geändert:/ – zzheads

+0

@zzheads Was für ein Durcheinander, die Frage ist nicht mehr echt. Ich muss die Frage in den echten Zustand ändern. –

Antwort

1

Mal sehen was wir haben:

Auf der Eigentümerseite der nm Beziehung:

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) 
@JoinTable(name = "news_hashTag", 
     joinColumns = @JoinColumn(name = "news_id"), 
     inverseJoinColumns = @JoinColumn(name = "hashtag_id")) 
public Set<HashTag> getHashTags() { 
    return hashTags; 
} 

Sie bieten nicht den Ausschluß von null Werten, da Dokumentation spezifiziert:

boolean nullable() default true;

Das ist falsch für die relationtable sowie die Ich würde. Sie müssen:

  1. Set die ID nullable=false.
  2. Legen Sie alle JoinColumns der JoinTable auf nullable=false fest.

Es gibt ein weiteres Problem: Sie machen einen Einsatz und ein Update von newsService.save(news); Sie einen Generator für die ID angeben, haben aber keinen Generator, dies in anderen Datenbanken in Ordnung ist, die so etwas wie eine nextval in Oracle bieten. In PostGreSQL sollten Sie wirklich ein Sequenzfeld wie dieses verwenden:

@Id 
@Column(name = "hashtag_id", nullable = false) 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "HashTagIDGenerator") 
@SequenceGenerator(name = "HashTagIDGenerator", sequenceName = "SEQ_HASHTAG_ID") 

Haben Sie eine gute Zeit.

+0

Zuerst vielen Dank für eine solche beschreibende Antwort. Alles wie vorgeschlagen geändert, aber haben denselben Fehler, für Fehlermeldung siehe Update meines Beitrags – zzheads

+0

@zzheads Warten Sie, das Update in Ihrer Frage ist ein Ergebnis meiner Änderungen? Du hast Logging-Informationen hinzugefügt, oder? Wenn die Logging-Informationen ein Ergebnis meiner Vorschläge sind, sollte dies nicht Teil der Frage sein. Fügen Sie die Logging-Informationen bitte als Kommentar zu meiner Antwort hinzu. –

+1

Ok, Fehlermeldung nach Änderungen, die Sie vorgeschlagen haben: Fehlermeldung: 48256 WARN --- [nio-8080-exec-1] ohengine.jdbc.spi.SqlExceptionHelper: SQL Fehler: 0, SQLState: 23502 2017- 02-12 13: 43: 24.445 FEHLER 48256 --- [nio-8080-exec-1] ohengine.jdbc.spi.SqlExceptionHelper: FEHLER: Nullwert in Spalte "news_id" verstößt gegen Nicht-Null-Bedingung Подробности: Eine fehlgeschlagene Zeile enthält (50, null, hashTag_1, null). – zzheads