Nowbody calls me Ignacio. I’m plunchete, man!

Apache OpenJPA 1.1.0 Now Available

Posted in Java, OpenJPA, OpenSource by plunchete on June 26, 2008

Apache OpenJPA 1.1.0 is now available at http://openjpa.apache.org/downloads.html and via Maven. Version 1.1.0 includes a number of new features and bugfixes, including:

  • Improvements in SQL generation for DB2, Oracle and MySQL
  • Support for memory-friendly streaming of BLOB and CLOB data
  • Support for interface-only domain models
  • Collections and Maps can now contain primitives, enums and @Embeddables, as well as @Entity and @MappedSuperclass types
  • Assorted performance and scalability improvements

For more details, see the release notes.

OpenJPA 1.1.0 was released some weeks ago but until yesterday we didn’t have a oficial announce, they has some problems with the artifacts signatures in maven.

The support for memory-friendly streaming of BLOB and CLOB data was my work in the summer of code 🙂

Streaming support for PostgreSQL in Apache OpenJPA

Posted in OpenJPA by plunchete on May 13, 2008

Hi all,

Yesterday was commited to the 1.1.0 branch my patch with Stream support in PostgreSQL. PostgreSQL uses a diferent table to save the Large Objects and now Apache OpenJPA does it in the right way, in my opinion is a good news to the people who works with OpenJPA and Postgres, now they have more funcionalities. I addition, I’ created some docs about the Streaming LOB support, and the JIRA issue is resolved. You can try it in the nightly snapshot relase, I think that it will be an official release soon. Now is the time to look for another issues to contribute with this project.

At the moment Apache OpenJPA has Streaming support in MySQL, Oracle, Micrsoft SQL Server and PostgreSQL.

I’m very happy to contribute with this community, also this is one of “my things to do this year“.

PS I promise to increase my post in this blog 🙂

My work in the Summer of Code

Posted in Google Summer of Code, OpenJPA by plunchete on September 11, 2007

Summer of Code finished at August 21th, but until yesterday my code didn’t part of the Apache OpenJPA project.

Since SoC finished I have refactored the tests classes, added new tests, added my Strategy in the MappingRepository and modified the DataCache, cache the streams is unadvisable, I have executed the tests in diferent databases and, for the moment, it runs in MySQL, SQL Server and Oracle. finally, after all those changes, my code was ready to check in.

Last several months were great, working in a OpenSource project, an important project, last several months I learned how OpenJPA works internally, and definetly I really enjoyed it!!.

When I started SoC my intention was continue contributing with the project that I have elected, and now after the SoC I’m sure that I’m going to continue contributing with the project.

Thanks Patrick for your work with me, and your help, you have been a fantastic mentor!! And, of course, thanks for your finally comment.

If someone wants to use this new feature, will need to download the latest SNAPSHOT and annotate the stream field (InputStream or Reader) like the example.

@Entity
public class Employee {
    ...
    @Persistent
    private InputStream photoStream;
...
}

And of course to use one the current databases supported.

JPQL and how to delete objects in JPA

Posted in Google Summer of Code, Java, JPA, OpenJPA by plunchete on May 30, 2007

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 😉

Relations with JPA

Posted in Google Summer of Code, Java, JPA, OpenJPA by plunchete on May 15, 2007

Continuing with the JPA Basic Example I’ve written another example with relations between Entities.

In the example we have three entities: Organization, Project, Student with this relations:

  • A organization has many projects
  • Each projects is asigned to one organization
  • A project has one student
  • Each student is asigned to one project

For this relations we need three anotations: @OneToOne, @OneToMany and @ManyToOne.

Now we are going to write our Organization entity:

@Entity
public class Organization {	

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "organization_id")
	private int idOrganization;

	@Basic
	@Column(nullable = false, length = 100)
	private String name;

	@OneToMany(cascade = CascadeType.ALL,
			mappedBy = "organization")
	@InverseLogical("organization")
	private ArrayList<Project> projects;

	public Organization(String name) {
		this.name = name;
	}
        // Getters and Setters
}

We used the anotation @OneToMany because we’re going to persist and Organization and we want to add projects to the organization and when we persist the organization the projects will be persist too.
The property cascade = CascadeType.ALL indicates that when we persist, remove, refresh or merge this entity all the entities held in this field would be persist, remove, delete or update. This property can have other values as:

  • CascadeType.PERSIST – When we persist and entity all the entities held in this field persist too. If you want to persist an entity and the fields dont use it fails.
  • CascadeType.REMOVE – When we delete an entity all the entities held in this field delete too.
  • CascadeType.REFRESH – When we refresh an entity all the entities held in this field refresh too.
  • CascadeType.MERGE – When we merde an entity all the entities held in this flied merged too

The following anotations are equivalent:

@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REMOVE,
             CascadeType.REFRESH, CascadeType.MERGE})
private ArrayList<Project> projects;

And

@OneToMany(cascade = CascadeType.ALL)
private ArrayList<Project> projects;

The propery mappedBy = “organization” indicates who’s the name of the organization entity in the project object.

The annotation @InverseLogical(“organization”) indicates that a field should be maintained bidirectionally. When we use this annotation OpenJPA managed the relation and updates the field oganization in the project entity.

Now we are going to write our Project entity:

@Entity
public class Project {	

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "project_id")
	private int idProject;

	@Basic
	@Column(nullable = false)
	private String name;

	@ManyToOne
	@JoinColumn(name="organization_id", nullable = false)
	private Organization organization;

	@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
	@JoinColumn(name="student_id")
	@InverseLogical("project")
	private Student student;

	public Project(String name) {
		this.name = name;
	}
        // Getters and Setters
}

Now we use the annotation @ManyToOne to indicate the relation.
The annotation @JoinColumn(name=”organization_id”, nullable = false) indicates that the field can’t be null and the name on the table.
And finally we use the annotation @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) to manage our one-to-one relation between the project entity and the student.

Now we are going to write our Student entity:

@Entity
public class Student {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int studentId;

	@Basic
	@Column(nullable = false)
	private String name;

	@OneToOne
	@JoinColumn(name="project_id")
	private Project project;

	public Student(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
        // Getters and Setters
}

And our persistence.xml:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    version="1.0">
    <persistence-unit name="example" transaction-type="RESOURCE_LOCAL">
        <class>example.Organization</class>
		<class>example.Project</class>
		<class>example.Student</class>
        <properties>
            <property name="openjpa.jdbc.SynchronizeMappings"
                value="buildSchema"/>
            <property name="openjpa.ConnectionURL"
                value="jdbc:mysql://localhost/OpenJPARelations"/>
            <property name="openjpa.ConnectionDriverName"
                value="com.mysql.jdbc.Driver"/>
            <property name="openjpa.ConnectionUserName"
                value="user"/>
            <property name="openjpa.ConnectionPassword"
                value="password"/>
	    <property name="openjpa.InverseManager"
		value="true"/>
	    <property name="openjpa.Log"
		value="File=../RelationsExample.log,
                DefaultLevel=WARN,SQL=TRACE"/>
        </properties>
    </persistence-unit>
</persistence>

The property openjpa.InverseManager is necesary to manage inverse relations.
Finally the writer and the reader:

public void insertValues() {
	EntityManagerFactory factory = Persistence.
		createEntityManagerFactory("example", System.getProperties());

	EntityManager em = factory.createEntityManager();
	em.getTransaction().begin();
	Organization organization =
		new Organization(" The Apache Software Foundation");

	Project project =
		new Project("Streaming LOB support (for OpenJPA)");
	Student student = new Student("Ignacio Andreu");
	project.setStudent(student);
	organization.addProject(project);

	project = new Project("Maven Dependency Visualization");
	student = new Student("Peter Kolbus");
	project.setStudent(student);
	organization.addProject(project);

	em.persist(organization);

	organization = new Organization(" Mono Project");
	project = new Project("Gendarme Tasks");
	student = new Student("Néstor Salceda");
	project.setStudent(student);
	organization.addProject(project);

	em.persist(organization);

	em.getTransaction().commit();
	em.close();
	factory.close();
}

public void readValues() {
	EntityManagerFactory factory = Persistence.
	createEntityManagerFactory("example", System.getProperties());

	EntityManager em = factory.createEntityManager();

	Query q = em.createQuery("select o from Organization o");

	for (Organization organization : (List)q.getResultList()) {
		System.out.println("Organization: "
			+ organization.getName());
		if (organization.getProjects() != null &&
			organization.getProjects().size() > 0) {
			for (Project p : organization.getProjects()) {
				System.out.println("-"
					+ p.getName()
                                        + " asigned to "
					+ p.getStudent().getName());
			}
		} else {
			System.out.println("No proyects yet");
		}
	}
	em.close();
	factory.close();
}

The output is:

[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 this is all for the moment!

Using OpenJPA

Posted in OpenJPA by plunchete on May 6, 2007

I’ve implemented a simple example using OpenJPA as persistence system. This is my first experience using OpenJPA and I like it, I think that OpenJPA is really a great API. I hope that this post serves as aid to other people who start with OpenJPA.

I started using the “hellojpa” example and the OpenJPA User’s Guide

Writting a simple persistence class:

@Entity
public class Person {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id_person")
	private long idPerson;

	@Basic
	@Column(nullable = false, length = 30)
	private String name;

	@Basic
	@Column(name = "e_mail")
	private String mail;

	public Person() {}

	public String getMail() {
		return mail;
	}

	public void setMail(String mail) {
		this.mail = mail;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public long getIdPerson() {
		return idPerson;
	}

	public void setIdPerson(long idPerson) {
		this.idPerson = idPerson;
	}
}

Annotations are very intuitive and powerful.

Writting the persistence.xml I used MySQL as database.

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    version="1.0">
    <persistence-unit name="example" transaction-type="RESOURCE_LOCAL">
        <class>example.Person</class>
        <properties>
            <property name="openjpa.jdbc.SynchronizeMappings"
                value="buildSchema"/>
            <property name="openjpa.ConnectionURL"
                value="jdbc:mysql://localhost/openjpa"/>
            <property name="openjpa.ConnectionDriverName"
                value="com.mysql.jdbc.Driver"/>
            <property name="openjpa.ConnectionUserName"
                value="user"/>
            <property name="openjpa.ConnectionPassword"
                value="password"/>
        </properties>
    </persistence-unit>
</persistence>

The property “openjpa.jdbc.SynchronizeMappings” is amazing, you don’t need any sql definitions of the tables or the rows, the OpenJPA creates the tables with your object information and if you add a variable it makes an alter automatically.

And finally contructing the EntityManage and saving the object:

        EntityManagerFactory factory = Persistence.
                createEntityManagerFactory("example", System.getProperties());

        EntityManager em = factory.createEntityManager();

        em.getTransaction().begin();

        Person person = new Person();
        person.setName("Ignacio Andreu");
        person.setMail("plunchete AT gmail DOT com");
        em.persist(person);

        em.getTransaction().commit();

        em.close();

And this is all 🙂