My Quotes


When U were born , you cried and the world rejoiced
Live U'r life in such a way that when you go
THE WORLD SHOULD CRY






Tuesday, March 13, 2018

JPA Static Meta Model

  1. When you write a criteria query or create a dynamic entity graph, you need to reference the entity classes and their attributes.
  2. The quickest and easiest way is to provide the required names as Strings.
  3. But this has several drawbacks, e.g. you have to remember or look-up all the names of the entity attributes when you write the query.
  4. But it will also cause even greater issues at later phases of the project, if you have to refactor your entities and change the names of some attributes.
  5. In that case you have to use the search function of your IDE and try to find all Strings that reference the changed attributes.
  6. This is a tedious and error prone activity which will easily take up the most time of the refactoring
  7. Use the static metamodel to write criteria queries and dynamic entity graphs.
  8. This is a small feature defined by the JPA specification which provides a type-safe way to reference the entities and their properties.
  1. The Metamodel Generator also takes into consideration xml configuration specified in orm.xml or mapping files specified in persistence.xml. However, if all configuration is in XML you need to add in at least on of the mapping file the following persistence unit metadata:
    
      
    
    
  2. Maven dependency: The jar file for the annotation processor can be found as below.
    
        org.hibernate
        hibernate-jpamodelgen
        1.0.0
    
    
  3. Maven compiler plugin configuration - direct execution

    
        maven-compiler-plugin
        
            1.6
            1.6
            
                org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
            
        
    
    
  4. Maven compiler plugin configuration - indirect execution
    
        maven-compiler-plugin
        
            1.6
            1.6
            -proc:none
        
    
    

  5. Configuration with maven-processor-plugin
    
        org.bsc.maven
        maven-processor-plugin
        2.0.5
        
            
                process
                
                    process
                
                generate-sources
                
                                                    
                        org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
                    
                
            
        
        
            
                org.hibernate
                hibernate-jpamodelgen
                1.2.0.Final
            
        
    
    
  6. Javac Task configuration
    As mentioned before, the annotation processor will run automatically each time the Java compiler is called, provided the jar file is on the classpath.


    
        
    
    
  7. IDE Configuration
  1. A simple entity for this example.
    @Entity
    @Table(name="ALERT")
    public class AlertEO implements java.io.Serializable{
    
     private static final long serialVersionUID = 1L;
     private Integer id;
     private String name;
     private String description;
     /**
      * method to get serial Id
      * 
      * @return id
      */
     @Id
     @Column(name="id")
     @GeneratedValue(strategy = GenerationType.AUTO)
     public Integer getId() {
      return id;
     }
     
     /**
      * Functions to get id
      * @return id
      */
     public void setId(Integer id){
      this.id = id;
     }
    
     /**
      * Functions to get name
      * @return name
      */
     @Column(name = "name")
     public String getName(){
      return name;
     }
     
     /**
      * Functions to set name
      * @return name
      */
     public void setName(String name){
      this.name = name;
     }
    
     /**
      * Functions to get description
      * @return description
      */
     @Column(name = "description")
     public String getDescription(){
      return description;
     }
    
     /**
      * Functions to set description
      * @return description
      */
     public void setDescription(String description){
      this.description=description;
     }
      /* (non-Javadoc)
      * @see java.lang.Object#toString()
      */
     @Override
     public String toString() {
      return "AlertEO [id=" + id + ", name=" + name + ", description=" + description + "]";
     }
    



  2. The class of the static metamodel looks similar to the entity.
    Based on the JPA specification, there is a corresponding metamodel class for every managed class in the persistence unit.
    You can find it in the same package and it has the same name as the corresponding managed class with an added ‘_’ at the end

    @Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
    @StaticMetamodel(AlertEO.class)
    public abstract class AlertEO_{
     public static volatile SingularAttribute<AlertEO, String>firstName;
     public static volatile SingularAttribute<AlertEO, String> lastName;
     public static volatile SetAttribute<AlertEO, Book> books;
     public static volatile SingularAttribute<AlertEO, Long> id;
     public static volatile SingularAttribute<AlertEO, Integer> version;
    }
    

  3. Using metamodel classes
  4. You can use the metamodel classes in the same way as you use the String reference to the entities and attributes.
  5. The APIs for criteria queries and dynamic entity graphs provide overloaded methods that accept Strings and implementations of the Attribute interface.

    CriteriaBuilder cb = this.em.getCriteriaBuilder();
    // create the query
    CriteriaQuey<AlertEO> q = cb.createQuery(AlertEO.class);
    // set the root class
    Root<AlertEO> a = q.from(AlertEO.class);
    // use metadata class to define the where clause
    q.where(cb.like(a.get(AlertEO_.name), "J%"));
    // perform query
    this.em.createQuery(q).getResultList();