如何为外部联接表字段编写@OrderBy批注以使用SQL对集合进行排序

时间:2016-10-27 09:13:51

标签: java hibernate annotations

有3张桌子。有" relatedCameraSet"的变量。需要通过" camera.name"使用SQL,但" camera.name"的字段不在" RelatedCamera"的表格中,在" Camera"的外部联接表中。 @OrderBy的以下注释不起作用。

@Entity
@Table(name = "MICRO_MAP")
public class MicroMap { //main table
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME", length = 32, nullable = false)
    private String name;

    @OneToMany(mappedBy="mapId",cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @OrderBy("camera.name") //OrderBy the field of "name" in Camera table 
    private Set<RelatedCamera> relatedCameraSet;

    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;
    }

    public Set<RelatedCamera> getRelatedCameraSet() {
        return relatedCameraSet;
    }

    public void setRelatedCameraSet(Set<RelatedCamera> relatedCameraSet) {
        this.relatedCameraSet = relatedCameraSet;
    }    
}

@Entity
@Table(name = "RELATED_CAMERA")
public class RelatedCamera {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name = "MAP_ID")
    private String mapId;

    @ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinColumn(name = "CAMERA_ID", referencedColumnName="id",nullable = true)
    private Camera camera;

    public Long getId() {
        return id;
    }

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

    public String getMapId() {
        return mapId;
    }

    public void setMapId(String mapId) {
        this.mapId = mapId;
    }

    public Camera getCamera() {
        return camera;
    }

    public void setCamera(Camera camera) {
        this.camera = camera;
    }    
}

@Entity
@Table(name = "CAMERA")
public class Camera {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME")
    private String name;

    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;
    }   
}

如何编写@OrderBy注释以使用SQL按摄像机名称对集合进行排序?

非常感谢!

2 个答案:

答案 0 :(得分:0)

我研究了您的问题,并从API文档中发现: Hibernate JPA 2.1 API

  

属性或字段名称必须与其中的关联类或嵌入类的持久属性或字段的名称相对应。

这就是为什么不能通过OrderBy来实现它,你只能通过MicroMap类的camera_id列进行排序。

你想要的是@Sort并实现Comparable接口或指定比较器:

Annotation Type Sort

答案 1 :(得分:0)

现在我意识到@OrderBy无法做到这一点,我认为通过实现Comparable接口或指定Comparator来做效率并不高效,因为完成任务需要两个步骤,第一步是从DB查询,第二步是在内存中排序。仅通过SQL获取排序集合是有效的。

为了获得高效率,我必须改变MicroMap的类别如下:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "MICRO_MAP")
public class MicroMap {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME", length = 32, nullable = false)
    private String name;

//    @OneToMany(mappedBy="mapId",cascade=CascadeType.ALL, fetch=FetchType.EAGER)
//    @OrderBy("camera.name") //OrderBy the field of "name" in Camera table, But JPA doesn't support
//    private Set<RelatedCamera> relatedCameraSet;

    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;
    }
}

并在DAO或Service类中添加方法。

public List<RelatedCamera> getRelatedCamera(Long mapId) {
    Session session = sessionFactory.getCurrentSession();
    List<RelatedCamera> list = session.createQuery(" from RelatedCamera where mapId="+mapId+" order by camera.name").list();
    return list;
}