@Override
  public void synchronizeMovie(MovieFile movieFile) {
    // If the file already exist in DB, keep current Movie, replace MovieFile
    List<MovieFileImpl> movieFiles =
        this.entityManager
            .createQuery(
                "SELECT m FROM MOVIE_FILE m WHERE m.absolutePath = ?1", MovieFileImpl.class)
            .setParameter(1, movieFile.getAbsolutePath())
            .getResultList();
    if (movieFiles != null && movieFiles.size() == 1) {
      movieFiles.get(0).getMovie().addFile(movieFile);
    }

    // Delete old MovieFiles
    this.entityManager
        .createQuery("DELETE FROM MOVIE_FILE m WHERE m.absolutePath = ?1")
        .setParameter(1, movieFile.getAbsolutePath())
        .executeUpdate();

    // Merge/Persist Movie/MovieFile into DB
    if (movieFile.getMovie() != null) {
      this.entityManager.merge(movieFile.getMovie());
    } else {
      // CD1 CD2 Part1 Part2 MovieFiles save into a same Movie
      List<MovieImpl> dbMovies =
          this.entityManager
              .createQuery(
                  "SELECT m FROM MOVIE m JOIN m.files f WHERE f.filePath = ?1 AND f.movieName = ?2",
                  MovieImpl.class)
              .setParameter(1, movieFile.getFilePath())
              .setParameter(2, movieFile.getMovieName())
              .getResultList();
      if (dbMovies != null && dbMovies.size() > 0) {
        Movie movie = dbMovies.get(0);
        movie.addFile(movieFile);
        this.entityManager.merge(movie);
      } else {
        // TODO: Should use factory here
        Movie movie = new MovieImpl();
        movie.addFile(movieFile);
        this.entityManager.persist(movie);
      }
    }

    // Delete empty movies
    this.entityManager.createQuery("DELETE FROM MOVIE m WHERE SIZE(m.files) = 0").executeUpdate();
  }