Подсчет количества элементов с использованием Hibernate / JPA или JdbcTemplate - PullRequest
0 голосов
/ 02 мая 2018

Я новичок в Spring / Hibernate / JPA. У меня есть класс сущности MovieEntity и MovieVersionEntity. У MovieEntity есть немного деталей о фильме (например, жанр фильма), но у MovieVersionEntity есть больше деталей о нем (имя, режиссер ...). Поэтому я хочу посчитать количество фильмов (MovieVersionEntity), связанных с MovieEntity для данного типа.

MovieEntity:

@Entity(name="MovieEntity")
@Table(name="Movie")
public class MovieEntity {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="Id")
    private long id;

    @Column(name="IsDeleted")
    private boolean isDeleted;

    @Column(name="ModifiedDate")
    @Temporal(TemporalType.TIMESTAMP)
    private Date modifiedDate;

    @OneToOne()
    @JoinColumn(name="MovieTypeId")
    private MovieTypeEntity movieTypeEntity;

    @OneToMany(mappedBy="movieEntity",optional = false)
    private List<MovieVersionEntity> movieVersionEntity;

    @Transient
    //@Formula("select count(*) from movie_version mv where mv.id=id")
    private int childCount;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public boolean isDeleted() {
        return isDeleted;
    }

    public void setDeleted(boolean isDeleted) {
        this.isDeleted = isDeleted;
    }

    public MovieTypeEntity getMovieTypeEntity() {
        return movieTypeEntity;
    }

    public void setMovieTypeEntity(MovieTypeEntity movieTypeEntity) {
        this.movieTypeEntity = movieTypeEntity;
    }

    public Date getModifiedDate() {
        return modifiedDate;
    }

    public void setModifiedDate(Date modifiedDate) {
        this.modifiedDate = modifiedDate;
    }

    public MovieVersionEntity getMovieVersionEntity() {
        return movieVersionEntity;
    }

    public void setMovieVersionEntity(MovieVersionEntity movieVersionEntity) {
        this.movieVersionEntity = movieVersionEntity;
    }

    public int getChildCount() {
        return childCount;
    }

    public void setChildCount(int childCount) {
        this.childCount = childCount;
    }
}

MovieVersionEntity

@Entity(name = "MovieVersionEntity")
@Table(name="MovieVersion")
//@EntityListeners(AuditingEntityListener.class)
public class MovieVersionEntity {

    @Id()
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="MovieId")
    private long movieId;

    @NotBlank
    @Column(name="MovieName")
    private String movieName;

    @NotBlank
    @Column(name="DirectorName")
    private String directorName;

    @NotBlank
    @Column(name="Description")
    private String description;

    @Column(name="StopDate")
    @Temporal(TemporalType.TIMESTAMP)
    private Date stopDate;

    @Column(name="DoneWatching")
    private boolean doneWatching;

    @Column(name="WatchDate")
    @Temporal(TemporalType.TIMESTAMP)
    //@CreatedDate
    private Date watchDate;

    @Column(name="ModifiedDate")
    @Temporal(TemporalType.TIMESTAMP)
    //@LastModifiedDate
    private Date modifiedDate;

    @ManyToOne(optional = false)
    @JoinColumn(name="Id")
    private MovieEntity movieEntity;

    public String getMovieName() {
        return movieName;
    }

    public void setMovieName(String movieName) {
        this.movieName = movieName;
    }

    public String getDirectorName() {
        return directorName;
    }

    public void setDirectorName(String directorName) {
        this.directorName = directorName;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Date getStopDate() {
        return stopDate;
    }

    public void setStopDate(Date stopDate) {
        this.stopDate = stopDate;
    }

    public boolean isDoneWatching() {
        return doneWatching;
    }

    public void setDoneWatching(boolean doneWatching) {
        this.doneWatching = doneWatching;
    }

    public Date getWatchDate() {
        return watchDate;
    }

    public void setWatchDate(Date watchDate) {
        this.watchDate = watchDate;
    }

    public Date getModifiedDate() {
        return modifiedDate;
    }

    public void setModifiedDate(Date modifiedDate) {
        this.modifiedDate = modifiedDate;
    }

    public long getMovieId() {
        return movieId;
    }

    public void setMovieId(long movieId) {
        this.movieId = movieId;
    }

    public MovieEntity getMovieEntity() {
        return movieEntity;
    }

    public void setMovieEntity(MovieEntity movieEntity) {
        this.movieEntity = movieEntity;
    }
}

Я написал запрос, но получаю ошибку sql

@Query(value = "select m.*, ct.ChildCount" +
            "from (" +
            "select mv.id, count(movie_id) as ChildCount " +
            "from movie_version mv " +
            "group by mv.id" +
            ") as ct join movie m " +
            "on ct.id = m.id;",nativeQuery = true)
    List<MovieEntity> getMoviesWithCount();

Error
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select mv.id, count(movie_id) as ChildCount from movie_version mv group by mv.id' at line 1
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_60]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_60]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_60]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422) ~[na:1.8.0_60]
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) ~[mysql-connector-java-5.1.44.jar:5.1.44]
    at 

Кроме того, я не уверен, что это правильный способ сделать это. Есть ли другой способ сохранить счетчик в переменной Transient. Я тоже пытался использовать @Formuala, но это не дает мне счет 0.

Формула: @Formula ("выберите количество (*) из mv movie_version, где mv.id = id")

Это первый раз, когда я имею дело с переменной Transient, и я не уверен, как она отображается на сущность, если она не сохранена в БД.

1 Ответ

0 голосов
/ 03 мая 2018

Однако @Formula работал на меня. @Transient и @Formula не могут идти вместе. @Formula только для чтения, поэтому мне не нужно беспокоиться о сохранении данных.

http://outbottle.com/hibernate-populating-an-unmapped-entity-field-with-count-using-formula/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...