Can we define all the Named Queries at one place like some property file instead of writing in the entity class

时光毁灭记忆、已成空白 提交于 2019-12-07 06:15:30

问题


How to Define All Named Queries in One place (like class) instead of writing the NamedQuery in top of Entity class.

For Example i have a base class. In this class i can define all named queries.

Base.java

@Entity
@NamedQueries({
    @NamedQuery(name="Student.findAll", query="SELECT s FROM Student s"),
    @NamedQuery(name="Employee.findAll", query="SELECT e FROM Employee e")})    
class Base {

}

Assume now i have two entities like Student and Employee. Now i want to access the Named query from Base class. It is possible to access. If is possible then how.

class Employee {

}

class Student {

}

In employee class, Student i want to access the named query from Base class. It is possible. If it is possible how i can access.


回答1:


We did a similar thing on one project. We had one entity that contained all of our named queries and (as @jimfromsa already said) they are accessible to your code wherever you need them because you are calling them by their unique name.

@Entity
@NamedQueries({
    @NamedQuery(name="Student.findAll", query="SELECT s FROM Student s"),
    @NamedQuery(name="Employee.findAll", query="SELECT e FROM Employee e"), 
    ...
    @NamedQuery(name="SomeEntity.someQuery", query="SELECT se FROM SomeEntity se")
})
public class NamedQueryHolder implements Serializable {
    // entity needs to have an id
    @Id
    private Integer id;

    // getter and setter for id
}

Note that this entity doesn't need to be mapped to an existing table, as long as you don't use it anywhere in the code. At least this approach worked with EclipseLink, never tried it with Hibernate.

In your case, if you don't want this extra query holder entity, you can put all named queries in Base class and it will work. However, I don't think it is a good idea to access named queries from your entity classes, they are called POJOs for a reason. Then again, it is all a matter of design (take a look at Anemic Domain Model).




回答2:


If you don't want the named queries to be mingled in your entity codes, you can store them in separate XML files like this:

employee.xml:

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" 
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm  
                 http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0">

  <package>mypersistenceunit</package>

  <named-query name="Employee.findAll">
    <query><![CDATA[SELECT e FROM Employee e]]></query>
  </named-query>
</entity-mappings>

student.xml:

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" 
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm  
                 http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0">

  <package>mypersistenceunit</package>

  <named-query name="Student.findAll">
    <query><![CDATA[SELECT e FROM Employee e]]></query>
  </named-query>
</entity-mappings>

Then you can include them in your persistence.xml like this:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence     
             http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
             version="1.0">

  <persistence-unit name="some-persistence-unit">
    <jta-data-source>java:/someDS</jta-data-source>

    <!-- Named JPQL queries per entity, but other organization is possible  -->
    <mapping-file>META-INF/employee.xml</mapping-file>
    <mapping-file>META-INF/student.xml</mapping-file>
  </persistence-unit>
</persistence>

Now you should be able to call these named queries from your Employee and Student classes by invoking EntityManager.createNamedQuery().

This way, you don't have to create a Base class just to store queries.




回答3:


Named queries are found by hibernate so they should be available to the hibernate session no matter which entity they are declared in.

@Entity
@NamedQueries({
    @NamedQuery(name="Employee.findAll", query="SELECT e FROM Employee e")
     })
class Employee {

}

@Entity
@NamedQueries({
    @NamedQuery(name="Student.findAll", query="SELECT s FROM Student s"),
    })
class Student {

}

Then you would be able to use them by using the hibernate session.

SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();

//HQL Named Query Example
Query query = session.getNamedQuery("Student.findAll");
List<Student> empList = query.list();
for Student student : studentList) {
    System.out.println("List of Students::" + student.getId() + ","
            + student.getAddress().getCity());
}

// rolling back to save the test data
tx.commit();
// closing hibernate resources
sessionFactory.close();

See http://www.journaldev.com/3451/hibernate-named-query-example-tutorial-namedquery-annotation-join-hql-native-sql for more info on named queries with hibernate se




回答4:


Finally MySelf i found the Answer.

Base.java

 @Entity
    @NamedQueries({ @NamedQuery(name="Employee.findAll", query = "SELECT e FROM Employee e"), 
                    @NamedQuery(name="Student.findAll", query = "SELECT s FROM Student s") })

    public class Base {
        @Id
        private long id;

    }

Employee.java

import java.io.Serializable;

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="Employee")
public class Employee implements Serializable {
    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO)
    private long id;

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

    @Column(name="salary")
    private float salary;

    // Setters and getters
}

Student.java

 import java.io.Serializable;        
 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="Student")
public class Student implements Serializable {
    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO)
    private long id;

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

    @Column(name="salary")
    private float salary;

    // setters and getters
}

Application.java

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

public class Application {
    private static String PERSISTENCE_UNIT_NAME = "EmployeeService";
    public static void main(String[] args) {
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        EntityTransaction entityTransaction = entityManager.getTransaction();

        // Before executing this query insert some records

        Query query = entityManager.createNamedQuery("Employee.findAll", Employee.class);
        query.setFirstResult(0);
        query.setMaxResults(10);

        @SuppressWarnings("unchecked")
        List<Employee> employees = query.getResultList();
        System.out.println(" \n "+employees);

        /*Student student = new Student();
        student.setName("Ranga");
        student.setSalary(15000);
        try {       
            entityTransaction.begin();
            entityManager.persist(student);
            System.out.println("Student Information: "+student);
            entityTransaction.commit();         
        } catch(PersistenceException ex) {          
            entityTransaction.rollback();
        }*/

        // Before executing this query insert some records

        query = entityManager.createNamedQuery("Student.findAll", Student.class);
        query.setFirstResult(0);
        query.setMaxResults(10);

        @SuppressWarnings("unchecked")
        List<Student> students = query.getResultList();
        System.out.println(" \n "+students);        

    }
}


来源:https://stackoverflow.com/questions/26838032/can-we-define-all-the-named-queries-at-one-place-like-some-property-file-instead

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!