Search code examples
javahibernatehibernate-criteria

Hibernate CreateCriteria for dependent class


I am working on an application where I have to display data/information about the vehicle details. I have 2 tables make and model with make_id being the foreign key in model table. I have 2 entity classes Make and Model as shown below:

@Entity
@Table(name = "make")
@PrimaryKeyJoinColumn(name="make_id")
public class Make {
    @Id
    @Column(name = "make_id")
    private String makeId;

    @Column(name = "make_name")
    private String makeName;

    @ManyToOne
    @JoinColumn(name = "mfg_unit_id")
    private MfgUnit mfgUnit;

    // Getter and Setters
}


@Entity
@Table(name = "model")
public class Model {
    @Id
    @Column(name = "model_id")
    private String modelId;

    @Column(name = "model_creation_date")
    private Date modelCreationDate;

    @Column(name = "make_id")
    private long makeId;

    @ManyToOne
    @JoinColumn(name = "make_id")
    private Make make;

    // Getter and Setters
}

I am able to retrieve all the Makes, but my requirement is to only retrieve the Makes for which the model_creation_date is between today and last 30 days. Can anyone help me with how to build the Hibernate criteria for this?


Solution

  • there can be another solution, but to achieve this you need to modify your Make class as following introducing a new relationship (@OneToMany) with Model class:

    @Entity
    @Table(name = "make")
    @PrimaryKeyJoinColumn(name="make_id")
    public class Make {
        @Id
        @Column(name = "make_id")
        private String makeId;
    
        @Column(name = "make_name")
        private String makeName;
    
        // ** introduced new relationship **
        @OneToMany(mappedBy="make", fetch = FetchType.LAZY)
        private List<Model> models;
    
        @ManyToOne
        @JoinColumn(name = "mfg_unit_id")
        private MfgUnit mfgUnit;
    
        // Getter and Setters
    }
    
    

    And keep the 'Model' class as it is:

    @Entity
    @Table(name = "model")
    public class Model {
        @Id
        @Column(name = "model_id")
        private String modelId;
    
        // change the datatype as Date or similar Datatype
        @Column(name = "model_creation_date")
        private Date modelCreationDate;
    
        @Column(name = "make_id")
        private long makeId;
    
        @ManyToOne
        @JoinColumn(name = "make_id")
        private Make make;
    
        // Getter and Setters
    }
    

    Once you have the relationship with 'Model' from 'Make' you can execute the following code to get your result:

    Calendar cal = Calendar.getInstance();
    // today 
    Date toDate=cal.getTime(); 
    cal.add( Calendar.DATE, -30 );
    //date before 30 days
    Date fromDate=cal.getTime();
    
    
    Criteria criteria = session.createCriteria(Make.class , "m")
            .createAlias("models", "s")
            .add(Restrictions.between("s.modelCreationDate",  fromDate, toDate))
            // if the above condition dosen't give you exact result you may try following(2)
            // try gt or lt ... as needed 
            //.add(Restrictions.ge("publicationDate", fromDate)) 
            //.add(Restrictions.le("publicationDate", fromDate))
            .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
    
    List<Make> ll2 = criteria.list();