我正在尝试使用hibernate建模以下关系: ProcessedUrl有一组句子。每个句子都有对拥有它的URL的引用,它还包含一个单词列表。每个Word都有一组包含它的句子。这是我写的代码:
@Entity
public class ProcessedUrl {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Type(type = "text")
private String url;
private Date date;
@OneToMany(mappedBy = "processedUrl")
@Cascade({CascadeType.MERGE, CascadeType.SAVE_UPDATE})
private Set<Sentence> sentences = new HashSet<>();
public ProcessedUrl() {}
public ProcessedUrl(String url, Date date) {
this.url = url;
this.date = date;
}
// getters, setters
}
@Entity
public class Sentence {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@ManyToMany
@OrderColumn(name="word_index")
@JoinTable(name = "word_sentence",
joinColumns = {@JoinColumn(name = "sentence_id")},
inverseJoinColumns = {@JoinColumn(name="word_id")})
@Cascade({CascadeType.MERGE, CascadeType.SAVE_UPDATE})
private List<Word> words = new ArrayList<>();
@ManyToOne
@JoinColumn(name = "urlId")
private ProcessedUrl processedUrl;
public Sentence() {}
// getters, setters
}
@Entity
public class Word {
@Id
@Column(length = 255)
private String content;
@ManyToMany(mappedBy = "words")
private Set<Sentence> sentences = new HashSet<>();
public Word() {}
public Word(String content) {
this.content = content;
}
// getters, setters
}
当我尝试插入新的ProcessedUrl及其内容
时会出现问题public void index() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
ProcessedUrl processedUrl = new ProcessedUrl(url, new Date());
List<String> sentences = getSentences();
sentences.forEach(sentenceContent -> {
Sentence sentence = new Sentence();
List<Word> words = wordsFromSentence(sentenceContent);
sentence.getWords().addAll(words);
sentence.setProcessedUrl(processedUrl);
words.forEach(w -> w.getSentences().add(sentence));
processedUrl.getSentences().add(sentence);
});
session.merge(processedUrl);
transaction.commit();
session.close();
}
private List<Word> wordsFromSentence(String sentenceContent) {
return Arrays.stream(sentenceContent.split("\\s+"))
.map(word -> word.replaceAll("[^\\w]", ""))
.filter(s -> !s.isEmpty())
.map(Word::new)
.collect(Collectors.toList());
}
此代码在数据库中给出了错误
ERROR: Duplicate entry 'google' for key 'PRIMARY'
我的问题是如何更改我的代码,以便hibernate不会尝试多次将相同的单词插入数据库。