使用Hibernate / JPA或JdbcTemplate计算Item的数量

时间:2018-05-02 15:21:20

标签: spring hibernate jpa

我是Spring / Hibernate / JPA的新手。我有一个实体类MovieEntity和MovieVersionEntity。 MovieEntity没有关于电影的细节(如电影类型),但MovieVersionEntity有更多关于它的细节(名字,导演......)。所以我想计算与给定类型的MovieEntity相关联的电影数量(MovieVersionEntity)。

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 

另外,我不确定这是否是一种正确的方法。有没有其他方法可以保存瞬态变量中的计数。我也试过使用@Formuala,但这并没有给我0计数。

式: @Formula(“从movie_version mv中选择计数(*),其中mv.id = id”)

这是我第一次处理Transient变量,如果它没有在db中持久存在,我不确定它是如何映射到实体的。

1 个答案:

答案 0 :(得分:0)

然而,@ Formula为我工作。 @Transient和@Formula不能一起去。 @Formula是只读的,因此我不必担心数据被保留。

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