@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();
  }
 @Override
 public void synchronizeMovie(String movieId, List<MovieInfo> movieInfoList) {
   Movie movie = this.entityManager.find(MovieImpl.class, movieId);
   if (movie != null) {
     List<? extends MovieInfo> existMovieInfoList = movie.getInfo();
     loop:
     for (MovieInfo movieInfo : movieInfoList) {
       if (existMovieInfoList != null && !existMovieInfoList.isEmpty()) {
         for (MovieInfo existMovieInfo : existMovieInfoList) {
           if (existMovieInfo.getProviderName().equalsIgnoreCase(movieInfo.getProviderName())) {
             continue loop;
           }
         }
       }
       // Not exist in databased
       movie.addInfo(movieInfo);
     }
     this.entityManager.merge(movie);
   }
 }
  @Override
  public void deleteMovie(String path) {
    List<MovieFileImpl> movieFiles;
    // No file extension, should be a directory
    if (StringUtils.isEmpty(FilenameUtils.getExtension(path))) {
      if (!path.endsWith(SystemUtils.FILE_SEPARATOR)) {
        path = path + SystemUtils.FILE_SEPARATOR;
      }
      path = FilenameUtils.separatorsToUnix(path);
      movieFiles =
          this.entityManager
              .createQuery(
                  "SELECT m FROM MOVIE_FILE m WHERE m.filePath LIKE ?1", MovieFileImpl.class)
              .setParameter(1, path + "%")
              .getResultList();
    }
    // Path is file
    else {
      path = FilenameUtils.separatorsToUnix(path);
      movieFiles =
          this.entityManager
              .createQuery(
                  "SELECT m FROM MOVIE_FILE m WHERE m.absolutePath = ?1", MovieFileImpl.class)
              .setParameter(1, path)
              .getResultList();
    }

    // Delete old movies
    if (movieFiles != null && !movieFiles.isEmpty()) {
      for (MovieFile movieFile : movieFiles) {
        Movie movie = movieFile.getMovie();
        if (movie != null && movie.getFilesCount() == 1) {
          this.entityManager.remove(movie);
        } else {
          this.entityManager.remove(movieFile);
        }
      }
    }
  }