/* * Hibernate OGM, Domain model persistence for NoSQL datastores * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.ogm.datastore.neo4j.test.query.nativequery; import static org.fest.assertions.Assertions.assertThat; import static org.hibernate.ogm.datastore.neo4j.test.query.nativequery.OscarWildePoem.TABLE_NAME; import java.util.GregorianCalendar; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.Query; import org.hibernate.ogm.backendtck.jpa.Poem; import org.hibernate.ogm.datastore.impl.DatastoreProviderType; import org.hibernate.ogm.utils.PackagingRule; import org.hibernate.ogm.utils.TestForIssue; import org.hibernate.ogm.utils.TestHelper; import org.hibernate.ogm.utils.jpa.OgmJpaTestCase; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; /** * Test the execution of native queries on Neo4j using the {@link EntityManager} * * @author Davide D'Alto <davide@hibernate.org> */ public class Neo4jEntityManagerNativeQueryTest extends OgmJpaTestCase { /* * The only purpose of this constant is to keep track of the nodes created using a native query via the * executeUpdate method. This is just a Label (not a table or entity). */ private static final String UPDATE_LABEL = "UPDATE"; @Rule public PackagingRule packaging = new PackagingRule( "persistencexml/ogm.xml", Poem.class ); private final Critic critic = new Critic( new CriticId( "de", "764" ), "Roger" ); private final OscarWildePoem portia = new OscarWildePoem( 1L, "Portia", "Oscar Wilde", new GregorianCalendar( 1808, 3, 10, 12, 45 ).getTime(), critic ); private final OscarWildePoem athanasia = new OscarWildePoem( 2L, "Athanasia", "Oscar Wilde", new GregorianCalendar( 1810, 3, 10 ).getTime(), null ); private EntityManager em; @Before public void init() throws Exception { em = createEntityManager(); persist( critic, portia, athanasia ); } @After public void tearDown() throws Exception { delete( portia, athanasia, critic ); em.close(); } @Test public void testIteratorSingleResultQuery() throws Exception { em.getTransaction().begin(); String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { name:'Portia', author:'Oscar Wilde' } ) RETURN n"; OscarWildePoem poem = (OscarWildePoem) em.createNativeQuery( nativeQuery, OscarWildePoem.class ).getSingleResult(); assertAreEquals( portia, poem ); em.getTransaction().commit(); } @Test public void testIteratorSingleResultFromNamedNativeQuery() throws Exception { em.getTransaction().begin(); OscarWildePoem poem = (OscarWildePoem) em.createNamedQuery( "AthanasiaQuery" ).getSingleResult(); assertAreEquals( athanasia, poem ); em.getTransaction().commit(); } @Test public void testListMultipleResultQuery() throws Exception { em.getTransaction().begin(); String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { author:'Oscar Wilde' } ) RETURN n ORDER BY n.name"; @SuppressWarnings("unchecked") List<OscarWildePoem> results = em.createNativeQuery( nativeQuery, OscarWildePoem.class ).getResultList(); assertThat( results ).as( "Unexpected number of results" ).hasSize( 2 ); assertAreEquals( athanasia, results.get( 0 ) ); assertAreEquals( portia, results.get( 1 ) ); em.getTransaction().commit(); } @Test public void testSingleResultQueryUsingParameter() throws Exception { em.getTransaction().begin(); String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { name:{name}, author:'Oscar Wilde' } ) RETURN n"; Query query = em.createNativeQuery( nativeQuery, OscarWildePoem.class ); query.setParameter( "name", "Portia" ); OscarWildePoem poem = (OscarWildePoem) query.getSingleResult(); assertAreEquals( portia, poem ); em.getTransaction().commit(); } @Test public void testSingleResultQueryUsingDateParameter() throws Exception { em.getTransaction().begin(); String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { dateOfCreation:{creationDate}, author:'Oscar Wilde' } ) RETURN n"; Query query = em.createNativeQuery( nativeQuery, OscarWildePoem.class ); query.setParameter( "creationDate", new GregorianCalendar( 1810, 3, 10 ).getTime() ); OscarWildePoem poem = (OscarWildePoem) query.getSingleResult(); assertAreEquals( athanasia, poem ); em.getTransaction().commit(); } @Test @TestForIssue(jiraKey = "OGM-702") public void testQueryWithCompositeId() throws Exception { em.getTransaction().begin(); @SuppressWarnings("unchecked") List<Critic> critics = em.createNativeQuery( "MATCH ( n:Critic ) RETURN n", Critic.class ).getResultList(); assertThat( critics ).onProperty( "id" ).containsExactly( new CriticId( "de", "764" ) ); em.getTransaction().commit(); } @Test @TestForIssue(jiraKey = "OGM-854") public void testToOneInitializedByQuery() throws Exception { em.getTransaction().begin(); String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { name:'Portia', author:'Oscar Wilde' } ) RETURN n"; OscarWildePoem poem = (OscarWildePoem) em.createNativeQuery( nativeQuery, OscarWildePoem.class ).getSingleResult(); assertThat( poem.getCritic() ).isNotNull(); assertThat( poem.getCritic().getName() ).as( "Wrong critic name" ).isEqualTo( "Roger" ); em.getTransaction().commit(); } @Test @SuppressWarnings("unchecked") public void testNativeQueryExecuteUpdate() throws Exception { em.getTransaction().begin(); String findQueryString = "MATCH (n:" + UPDATE_LABEL + ") RETURN n"; Query findQuery = em.createNativeQuery( findQueryString ); String createQuery = "CREATE (n:" + UPDATE_LABEL + " { author:'Giorgio Faletti' })"; int updates = em.createNativeQuery( createQuery ).executeUpdate(); if ( TestHelper.getCurrentDatastoreProviderType() != DatastoreProviderType.NEO4J_HTTP ) { assertThat( updates ).isEqualTo( 3 ); // 1 node + 1 label + 1 property set } List<Object> createdNode = (List<Object>) findQuery.getResultList(); assertThat( createdNode ).hasSize( 1 ); String deleteQuery = "MATCH (n:" + UPDATE_LABEL + ") DELETE n "; int deletes = em.createNativeQuery( deleteQuery ).executeUpdate(); if ( TestHelper.getCurrentDatastoreProviderType() != DatastoreProviderType.NEO4J_HTTP ) { assertThat( deletes ).isEqualTo( 1 ); // 1 node } List<Object> uniqueResult = (List<Object>) findQuery.getResultList(); assertThat( uniqueResult ).isEmpty(); em.getTransaction().commit(); } private void persist(Object... entities) { EntityManager em = createEntityManager(); em.getTransaction().begin(); for ( Object object : entities ) { em.persist( object ); } em.getTransaction().commit(); em.clear(); } private void assertAreEquals(OscarWildePoem expectedPoem, OscarWildePoem poem) { assertThat( poem ).isNotNull(); assertThat( poem.getId() ).as( "Wrong Id" ).isEqualTo( expectedPoem.getId() ); assertThat( poem.getName() ).as( "Wrong Name" ).isEqualTo( expectedPoem.getName() ); assertThat( poem.getAuthor() ).as( "Wrong Author" ).isEqualTo( expectedPoem.getAuthor() ); } @Override public Class<?>[] getAnnotatedClasses() { return new Class<?>[] { OscarWildePoem.class, Critic.class }; } private void delete(Object... entities) { em.getTransaction().begin(); for ( Object object : entities ) { Object entity = em.merge( object ); em.remove( entity ); } em.getTransaction().commit(); em.clear(); } private EntityManager createEntityManager() { return getFactory().createEntityManager(); } }