问题
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