Search code examples
javahibernatecriteriacriteria-apidetachedcriteria

Hibernate Criteria: How to retrieve table data with foreign key relationship


I have two pojo classes wihch are named Document and DocumentUser. DocumentUser has an property documentId which linked to Document's id by foreign key. So i want to create criteria query which retrieve Documents with its DocumentUser which is linked itself by forein key("document_id")

pojo classes:

Document

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@Entity
@Table(name = "DYS_BYS_DOSYA")
@Audited
public class Document implements Serializable {

    private Long id;
    private String name;

    private List<DocumentUser> documentUserList = new ArrayList<DocumentUser>();

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID", nullable = false, precision = 15, scale = 0)
    public Long getId() {
        return id;
    }

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

    @Column(name = "AD", nullable = false, length = 500)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @OneToMany(mappedBy = "document", fetch = FetchType.EAGER)
    @Fetch(FetchMode.SUBSELECT)
    @Cascade(CascadeType.ALL)
    public List<DocumentUser> getDocumentUserList() {
        return documentUserList;
    }

    public void setDocumentUserList(List<DocumentUser> documentUserList) {
        this.documentUserList = documentUserList;
    }

    @Override
    public String toString() {
        return "tr.com.enlil.dys.server.servis.model.Document[id=" + id + "]";
    }
}

DocumentUser:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@Entity
@Table(name = "DYS_DOSYA_SAHIBI_USER")
@Audited
public class DocumentUser implements Serializable {


    /**
     * 
     */
    private static final long serialVersionUID = 6393919788296838129L;

    private Long id;
    private Long personelId;
    private Document document;

    private String personelName;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID", unique = true, nullable = false, precision = 15, scale = 0)
    public Long getId() {
        return id;
    }

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

    @Column(name = "OLUSTURUCU_PERSONEL_ID")
    public Long getPersonelId() {
        return personelId;
    }

    public void setPersonelId(Long personelId) {
        this.personelId = personelId;
    }

    @Column(name = "KULLANICI_AD")
    public String getPersonelName() {
        return personelName;
    }

    public void setPersonelName(String personelName) {
        this.personelName = personelName;
    }

    @ManyToOne
    @JoinColumn(name = "DOSYA_ID")
    public Document getDocument() {
        return document;
    }

    public void setDocument(Document document) {
        this.document = document;
    }
}

In this way, how can i get Document data depends on personelId of DocumentUser table by using criteria query? I am not familiar with hibernate and i need your helps. I try to write some codes but didn't work.

public List<Document> fetchRecordsByCriteriaLimitedList(String userId) throws Exception{
        Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(Dosya.class);

        DetachedCriteria dosyaSahibiCriteria = (DetachedCriteria) criteria.createCriteria("documentUserList");
        dosyaSahibiCriteria.add(Restrictions.eq("personelId", userId));
        dosyaSahibiCriteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

            return criteria.list();

    }

Solution

  • Several problems with your code. First of all, you said

    2)DocumentUser is subclass of Document

    This isn't true, judging from your code (it would mean that DocumentUser extends Document), but you probably meant they are in a parent -> child relation. Second, in documentUserList mapping, there is this @OneToMany(mappedBy = "dosya", fetch = FetchType.EAGER), which means there is a field named dosya in DocumentUser, and there isn't. Instead, replace it with mappedBy = "document". Assuming everything else is ok, query to get all documents based on their DocumentUser's id would be

    public List<Document> fetchRecordsByCriteriaLimitedList(String userId) throws Exception{
        Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(Document.class);
        criteria.createAlias("documentUserList", "users").add(Restrictions.eq("users.personelId", userId));
        return criteria.list();
    }