John Steed
John Steed

Reputation: 629

How to avoid string members in hibernate?

Is it possible to avoid using string literials in Hibernate, such as in criteria restrictions and projections:

Criteria criteria = session.createCriteria(Employee.class)
                   .add(Restrictions.eq("name", "john doe"));

or

Projection p1 = Projection.property("name");

For example, in the code snippets above, replacing "name" with something.name , where something contains all the members of the Employee class.

It would make it less error prone, e.g. typo in the string.

EDIT: Updating question to be more general and not specific to just Criteria.

Upvotes: 3

Views: 769

Answers (3)

Yuri
Yuri

Reputation: 1765

You can turn on JPA's Metamodel generation and use generated classes' fields as type and name -safe "literals" with Criteria API. Example from Hibernate docs

@Entity
public class Order {
    @Id
    @GeneratedValue
    Integer id;

    @ManyToOne
    Customer customer;

    @OneToMany
    Set<Item> items;
    BigDecimal totalCost;
    // standard setter/getter methods
}

@StaticMetamodel(Order.class) // <<<<<<<<<< this class gets generated for you
public class Order_ {
    public static volatile SingularAttribute<Order, Integer> id;
    public static volatile SingularAttribute<Order, Customer> customer;
    public static volatile SetAttribute<Order, Item> items;
    public static volatile SingularAttribute<Order, BigDecimal> totalCost;
}
// type-safe and typo-proof building of query:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
SetJoin<Order, Item> itemNode = cq.from(Order.class).join(Order_.items);
cq.where( cb.equal(itemNode.get(Item_.id), 5 ) ).distinct(true);

It's very handy in case of big entities and complex queries. The only downside is that sometimes it becomes very verbose to use.
And it's JPA standard, so EclipseLink and other JPA providers support it as well.

Upvotes: 3

Jad Chahine
Jad Chahine

Reputation: 7159

You can create a Employee Constants class:

public class EmployeeConstants {
        public static final String firstName= "firstname";
        public static final String lastName= "lastname";
        ....
}

And call the field as :

Criteria criteria = session.createCriteria(Employee.class)
                   .add(Restrictions.eq(EmployeeConstants.firstName, "john doe"));

In fact EmployeeConstants.firstNamereturns firstname which must be the field name of the Employee Entity.

Upvotes: 1

Thor Stan
Thor Stan

Reputation: 86

in your case you can use a query by example:

Employee employee = new Employee();
employee.setName("john doe");
Example employeeExample = Example.create(employee);

Criteria criteria = session.createCriteria(Employee.class).add(employeeExample);

Upvotes: 0

Related Questions