Continuing with the example Relations with JPA now I’ve written another example about querys and deleting objects.
JPA includes a mechanism to write querys called JPQL (Java Persistence Query Language) in this example we’re going to execute some querys and deleting some objects and their relations.
At the end of the last article we had this values in database:
[java] Organization: The Apache Software Foundation
[java] -Streaming LOB support (for OpenJPA) asigned to Ignacio Andreu
[java] -Maven Dependency Visualization asigned to Peter Kolbus
[java] Organization: Mono Project
[java] -Gendarme Tasks asigned to Néstor Salceda
And the next relations between entities:
- A organization has many projects
- Each projects is asigned to one organization
- A project has one student
- Each student is asigned to one project
Ok, if we remember the last example we used a Query to list all the organizations
Query q = em.createQuery("select o from Organization o");
This is a simple Query, now we’re going to write a Query with a WHERE clause.
JPQL provides us two methods for parameterized queries. First is positional parameter, using an integer prefixed by a question mark and second is named parameter, using an string prefixed by a colon. We can populate the Query calling the setParameter method.
If we are writing a Query with a positional parameter:
Query query = em.createQuery(select o from Organization o "
+ "where o.name like ?1);
query.setParameter(1, "The Apache Software Foundation");
And if we are writing a Query with a named parameter:
Query query = em.createQuery(select o from Organization o "
+ "where o.name like :name);
query.setParameter("name", "The Apache Software Foundation");
EntityManager povides other method to search an object by his primary key, the method find. In our class Organization the primary key is an int value, auto-increment. In out table the value of the Organization calls “The Apache Software Foundation” is 1. If whe want to load our object by the primary key:
Organization organization = em.find(Organization.class, 1);
Now we are going to delete our organization called “Mono Project” using JPQL. The process is the same that a select.
Query query = em.createQuery(delete from Organization o "
+ "where o.name like :name);
query.setParameter("name", "Mono Project");
int deleted = query.executeUpdate();
The Query provides methods to get the result like getResultList() when we want a List or getSingleResult() when we’re sure that we only have one match. Also The Query provides a method to set the maximun number of results setMaxResults(int number)
And now we going to list all the projects
Query q = em.createQuery("select p from Project p");
for (Project project : (List)q.getResultList()) {
System.out.println("-"
+ project.getOrganization().getName()
+ " - " + project.getName()
+ " asigned to "
+ project.getStudent().getName());
}
The output is
[java] -Streaming LOB support (for OpenJPA) asigned to Ignacio Andreu
[java] -Maven Dependency Visualization asigned to Peter Kolbus
Wow, all the projects asigned to “Mono Project” have been deleted too (and all the student asigned to this projects). If we remember we have these relations
@Entity
public class Organization {
...
@OneToMany(cascade = CascadeType.ALL,
mappedBy = "organization")
@InverseLogical("organization")
private ArrayList<Project> projects;
...
@Entity
public class Project {
...
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name="student_id")
@InverseLogical("project")
private Student student;
...
It’s seems that our relations works
Another way is using the method remove of the EntityManager, but in this method we must indicate all the Object.
Query q = em.createQuery("select o from Organization o "
+ "where o.name like :name");
q.setParameter("name", "Mono Project");
// This is unsecure beacause name not is unique
// we can use the method setMaxResults(1)
Organization o = (Organization)q.getSingleResult();
em.remove(o);
The result is the same.
That is all, folks
Posted by plunchete
Posted by plunchete