Tuesday, June 21, 2016

Hibernate OGM + Apache DeltaSpike Data = Pure Love for NoSQL

If you haven't looked at it before, Hibernate OGM is a JPA implementation designed around NoSQL databases.  Since its a JPA implementation, it plugs in perfectly to Apache DeltaSpike's Data module.  The added support for NoSQL databases really is a strong suitor for cross platform support.

To start, we'll create a persistence.xml to represent our connection.


<persistence
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    version="2.1"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="MyPU" transaction-type="RESOURCE_LOCAL">
    <!-- Use the Hibernate OGM provider: configuration will be transparent -->
    <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>
    <properties>
      <property name="hibernate.ogm.datastore.provider" value="mongodb"/>
      <property name="hibernate.ogm.datastore.database" value="swarmic"/>
      <property name="hibernate.ogm.datastore.create_database" value="true"/>
    </properties>
  </persistence-unit>
</persistence>


This is copied pretty much verbatim from the user guide.  I'm using MongoDB.  Not for any particular reason other than I've used it before and it was already installed on my machine.  Next we'll create a repository and an entity:

@Entity
public class Employee {

    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name="uuid", strategy="uuid2")
    private String id;

    @Column(length = 40)

    private String name;
}

@Repository(forEntity = Employee.class)
public interface EmployeeRepository extends EntityPersistenceRepository{
    @Query("select e from Employee e order by e.name")
    Stream list();

}

Now we have a database layer that can save and retrieve entities.  Last thing we need is a REST endpoint to expose this.  To do that, we want to make sure its transactional since we're using resource local as well as providing some sane operations (create, list).  That endpoint probably looks like this

@Path("/")
@RequestScoped
@Produces("application/json")
@Transactional
public class EmployeeRest {
    @Inject
    private EmployeeRepository repository;
    @GET
    public Response list(@QueryParam("name") String name) {
        return Response.ok(repository.list().collect(toList())).build();
    }
    @GET
    @Path("/{id}")
    public Employee get(@PathParam("id") String id) {
        return repository.findBy(id);
    }
    @POST
    @Consumes("text/plain")
    public Response create(String name) {
        Employee employee = new Employee(name);
        Employee result = repository.save(employee);
        return Response.ok(result.getId()).build();
    }

}

So just like that, with in the ball park of 75 lines of code, we have a CDI based application that uses Hibernate OGM and Apache DeltaSpike that can list, get and create entities end to end.  That was super simple!