JPA多对多保存重复实体

问题描述 投票:0回答:1

我对JPA多对多单向关系有困难。问题是在DB中创建重复的Label实体,即使它们是相同的。出于性能原因,@ Id是生成的数字而不是Label.label。连接的问题是findByLabel()找不到这两个音符。

我阅读了很多文章和示例,我认为我有类似的代码,但它不起作用。任何帮助表示赞赏。

我正在使用Spring Boot,H2,Spring Data JPA。我正在寻找非XML,纯Java注释解决方案。

库:

public interface NoteRepository extends CrudRepository<Note, Long> {
    @Query("SELECT a from Note a where ?1 member of a.labels")
    List<Note> findByLabel(Label label); }

标签:

@Entity
public class Label {

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

    private String label;

    protected Label() {
    }

    public Label(String label) {
        this.label = label;
    }

    public Long getLabelId() {
        return labelId;
    }

    public void setLabelId(Long labelId) {
        this.labelId = labelId;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Label)) return false;

        Label label1 = (Label) o;

        return getLabel().equals(label1.getLabel());
    }

    @Override
    public int hashCode() {

        return Objects.hash(getLabel());
    }

    @Override
    public String toString() {
        return "Label{" +
                "labelId=" + labelId +
                ", label='" + label + '\'' +
                '}';
    }
}

注意:

@Entity
public class Note {

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

    private String note;

    @ManyToMany(
            fetch = FetchType.EAGER,
            cascade = CascadeType.ALL)
    @JoinTable(
            name = "Note_Label",
            joinColumns = @JoinColumn(
                    name = "NoteId",
                    referencedColumnName = "note_id"),
            inverseJoinColumns = @JoinColumn(
                    name = "LabelId",
                    referencedColumnName = "label_id"))
    private Set<Label> labels;


    protected Note() {
    }

    public Note(String note, Set<Label> labels) {
        this.note = note;
        this.labels = labels;
    }

    public Note(String note) {
        this(note, null);
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }


    public Long getNoteId() {
        return noteId;
    }

    public void setNoteId(Long noteId) {
        this.noteId = noteId;
    }

    public Set<Label> getLabels() {
        return labels;
    }

    public void setLabels(Set<Label> labels) {
        this.labels = labels;
    }

    @Override
    public String toString() {
        return "Note{" +
                "note='" + note + '\'' +
                ", labels='" + labels + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Note)) return false;

        Note note1 = (Note) o;

        if (!getNote().equals(note1.getNote())) return false;
        return getLabels() != null ? getLabels().equals(note1.getLabels()) : note1.getLabels() == null;
    }

    @Override
    public int hashCode() {
        int result = getNote() != null ? getNote().hashCode() : 0;
        result = 31 * result + (getLabels() != null ? getLabels().hashCode() : 0);
        return result;
    }
}

测试失败:

@SpringBootTest
@RunWith(SpringRunner.class)
public class NoteRepositoryTest {

    @Autowired
    private NoteRepository repository;


    @Test
    public void findByLabel() throws Exception {

        String labelAString = "labelA";

        Label labelA = new Label(labelAString);
        Label labelA1 = new Label(labelAString);
        Label labelB = new Label("labelB");
        Label labelC = new Label("labelC");

        Note note1 = new Note(
                "note1", new HashSet<Label>(Arrays.asList(
                labelA, labelB)));

        Note note2 = new Note(
                "note2", new HashSet<Label>(Arrays.asList(
                labelA1, labelC)));

        repository.deleteAll();


        repository.save(note1);
        repository.save(note2);


        List<Note> actualNotes = repository.findByLabel(labelA);

        System.out.println(actualNotes);


        assertTrue(actualNotes.size() == 2);
        assertTrue(actualNotes.containsAll(Arrays.asList(note1, note2)));

    }

}
java spring many-to-many spring-data-jpa
1个回答
0
投票

正确的代码:

@Test
public void saveAndGet() throws Exception {

    String labelAString = "labelA";

    Label labelA = new Label(labelAString);
    Label labelA1 = new Label(labelAString);
    Label labelB = new Label("labelB");
    Label labelC = new Label("labelC");

    repository.save(labelA);
    System.out.println(labelA.getLabelId());
    repository.save(labelB);

    Iterable<Label> all = repository.findAll();

    all.forEach(p ->{
        System.out.println(p.getLabel());
        System.out.println(p.getLabelId());
    });

}
© www.soinside.com 2019 - 2024. All rights reserved.