hibernate many to many и ошибка java.sql.SQLIntegrityConstraintViolationException: Duplicate entry

131
22 мая 2021, 19:30

Есть унаследованная база данных, пытаюсь построить вокруг нее приложение. Проблема в том что я получаю периодически Duplicate entry при попытке вставить данные в связанные таблицы.

К примеру есть сущность Video и есть сущность Actor. В каждом видео снимается множество актеров, и каждый актер снялся в нескольких фильмах, поэтому связь Many to many.


@Entity
@Table(name = "videos")
public class Video implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    private int year;
    @ManyToMany(cascade = {CascadeType.ALL})
    @JoinTable(
            name = "film_actors",
            joinColumns = @JoinColumn(name = "film_id"),
            inverseJoinColumns = @JoinColumn(name = "actor_id")
    )
    private Set<Actor> actors = new HashSet<>();
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Video video = (Video) o;
        return title != null ? title.equals(video.title) : video.title == null;
    }
    @Override
    public int hashCode() {
        return title != null ? title.hashCode() : 0;
    }
    //getters setters
}

@Entity
@Table(name = "actors")
public class Actor {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    @Column(unique = true)
    private String name;
    @ManyToMany(mappedBy = "actors")
    private Set<Video> video = new HashSet<>();
    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;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Actor actor = (Actor) o;
        return name != null ? name.equals(actor.name) : actor.name == null;
    }
    @Override
    public int hashCode() {
        return name != null ? name.hashCode() : 0;
    }
}

Проблема в том что когда я в своем сервисе пытаюсь сохранить новую сущность Video с актером который уже есть в таблице actors (с таким же именем), я получаю ошибку что он не может быть вставлен, и это рационально так как на таблице стоит ограничение уникальности на столбец Actor.name.

Какого поведения я жду? Я надеюсь что hibernate поймет что в таблицу Actors уже есть уникальное значение не будет в нее пытаться вставить снова актера с таким же именем возьмет его id и положит в связанную таблицу film_actor.

Это возможно сделать ?

сейчас я делаю что то вроде этого, что бы обойти мою проблему, это кажется не правильным решением. Это единственный путь ?

 @Override
    public void save(Video video) throws SQLException {
        Set<Actor> actors = video.getActors();
        Set<Actor> mapped = new HashSet<>();
        for (Actor actor : actors) {
            Actor fromDb = actorRepository.findByName(actor.getName());
            if (fromDb != null) {
                mapped.add(fromDb);
            } else {
                mapped.add(actor);
            }
        }
        video.setActors(mapped);
        videoRepository.save(video);
    }
READ ALSO
Почему именно system.out?

Почему именно system.out?

Почему когда мы хотим вывести текст на языке java мы пишем systemout ? что это значит, может кто помочь ?

105
$event.keyCode добавление символа

$event.keyCode добавление символа

может ктото сталкивался с похожей проблемойМне нужно добавить символ è в $event

99