Skip to content

Commit

Permalink
OGM-1375 Test avoiding use of partial entities
Browse files Browse the repository at this point in the history
  • Loading branch information
fax4ever authored and DavideD committed Mar 12, 2018
1 parent 58680cc commit de7c199
Show file tree
Hide file tree
Showing 6 changed files with 403 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* 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.backendtck.queries.projection;

import static org.fest.assertions.Assertions.assertThat;

import java.util.Collections;
import java.util.List;

import org.junit.Test;

/**
* Use of projection in JPQL query:
* if a projection is used on root Entity then the result must be an Object array instead of an Entity.
*
* @author Fabio Massimo Ercoli
*/
public class JPQLProjectionTest extends SingleMovieBaseTest {

public static final String JPQL_QUERY_WITHOUT_PROJECTION = "SELECT p FROM Movie p";
public static final String JPQL_QUERY_WITH_PROJECTION_ID_NAME = "SELECT p.id, p.name FROM Movie p";
public static final String JPQL_QUERY_WITH_PROJECTION_YEAR_AUTHOR = "SELECT p.year, p.author FROM Movie p";

@Test
public void testUniqueResultWithoutProjection() {
inTransaction( session -> {
Movie movie = (Movie) session.createQuery( JPQL_QUERY_WITHOUT_PROJECTION )
.uniqueResult();

assertThat( movie ).isEqualTo( originalMovie );
} );
}

@Test
public void testUniqueResultWithProjection() {
inTransaction( session -> {
Object movie = session.createQuery( JPQL_QUERY_WITH_PROJECTION_ID_NAME )
.uniqueResult();

assertThat( movie ).isEqualTo( new Object[] { 1, "2001: A Space Odyssey" } );
} );
}

@Test
public void testResultListWithoutProjection() {
inTransaction( session -> {
List<Movie> movies = session.createQuery( JPQL_QUERY_WITHOUT_PROJECTION )
.getResultList();

assertThat( movies ).isEqualTo( Collections.singletonList( originalMovie ) );
} );
}

@Test
public void testResultListWithProjection() {
inTransaction( session -> {
List<Object> movies = session.createQuery( JPQL_QUERY_WITH_PROJECTION_YEAR_AUTHOR )
.getResultList();

assertThat( movies.get( 0 ) ).isEqualTo( new Object[] { 1968, "Stanley Kubrick" } );
} );
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* 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.backendtck.queries.projection;

import java.util.Objects;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.SortableField;
import org.hibernate.search.annotations.Store;

@Entity
@Table(name = "Movie")
@Indexed
public class Movie {

@Id
private Integer id;

@Field(analyze = Analyze.NO, store = Store.YES)
@SortableField
private String name;

@Field(analyze = Analyze.NO, store = Store.YES)
@SortableField
private String author;

@Field(analyze = Analyze.NO, store = Store.YES)
@SortableField
private Integer year;

public Movie() {
}

public Movie(Integer id, String name, String author, int year) {
this.id = id;
this.name = name;
this.author = author;
this.year = year;
}

public Integer getId() {
return id;
}

@Override
public String toString() {
return "Movie{" +
"id=" + id +
", name='" + name + '\'' +
", author='" + author + '\'' +
", year=" + year +
'}';
}

@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
Movie movie = (Movie) o;
return Objects.equals( id, movie.id ) &&
Objects.equals( name, movie.name ) &&
Objects.equals( author, movie.author ) &&
Objects.equals( year, movie.year );
}

@Override
public int hashCode() {
return Objects.hash( id, name, author, year );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* 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.backendtck.queries.projection;

import static org.fest.assertions.Assertions.assertThat;

import java.util.List;
import javax.persistence.PersistenceException;

import org.hibernate.ogm.utils.TestForIssue;

import org.junit.Test;

/**
* Base test for use of a projection:
* if a projection is used on root Entity then the result must be an Object array instead of an Entity.
*
* addEntity native query parameter is not allowed then projection is used on root Entity.
*
* @author Fabio Massimo Ercoli
*/
public abstract class NativeQueryProjectionBaseTest extends SingleMovieBaseTest {

protected abstract String getNativeQueryWithoutProjection();
protected abstract String getNativeQueryWithProjectionIdName();
protected abstract String getNativeQueryWithProjectionYearAuthor();

@Test
public void testUniqueResultWithAddEntityWithoutProjection() {
inTransaction( session -> {
Movie movie = (Movie) session.createNativeQuery( getNativeQueryWithoutProjection() )
.addEntity( Movie.class )
.uniqueResult();

assertThat( movie ).isEqualTo( originalMovie );
} );
}

@Test
@TestForIssue( jiraKey = "OGM-1375" )
public void testUniqueResultWithAddEntityWithProjection() {
thrown.expect( PersistenceException.class );
thrown.expectMessage( PROJECTION_ADD_ENTITY_MESSAGE );

inTransaction( session -> {
session.createNativeQuery( getNativeQueryWithProjectionIdName() )
.addEntity( Movie.class )
.uniqueResult();
} );
}

@Test
public void testUniqueResultWithoutAddEntityWithProjection() {
inTransaction( session -> {
Object[] movie = (Object[]) session.createNativeQuery( getNativeQueryWithProjectionIdName() )
.uniqueResult();

// actually Neo4J remote http return always Integer type
// while Neo4J remote bolt return always Long type
// regardless the fact that type declared on the Entity is an Integer or a Long
assertThat( ( (Number) movie[0] ).intValue() ).isEqualTo( 1 );
assertThat( movie[1] ).isEqualTo( "2001: A Space Odyssey" );
} );
}

@Test
public void testResultListWithAddEntityWithoutProjection() {
inTransaction( session -> {
List<Movie> movies = session.createNativeQuery( getNativeQueryWithoutProjection() )
.addEntity( Movie.class )
.getResultList();

assertThat( movies.get( 0 ) ).isEqualTo( originalMovie );
} );
}

@Test
@TestForIssue( jiraKey = "OGM-1375" )
public void testResultListWithAddEntityWithProjection() {
thrown.expect( PersistenceException.class );
thrown.expectMessage( PROJECTION_ADD_ENTITY_MESSAGE );

inTransaction( session -> {
session.createNativeQuery( getNativeQueryWithProjectionYearAuthor() )
.addEntity( Movie.class )
.getResultList();
} );
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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.backendtck.queries.projection;

import org.hibernate.ogm.utils.OgmTestCase;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.ExpectedException;

/**
* @author Fabio Massimo Ercoli
*/
public abstract class SingleMovieBaseTest extends OgmTestCase {

protected static final String PROJECTION_ADD_ENTITY_MESSAGE = "OGM000091: Projection and addEntity are not allowed in the same query on <Movie> ";

@Rule
public ExpectedException thrown = ExpectedException.none();

protected final Movie originalMovie = new Movie( 1, "2001: A Space Odyssey", "Stanley Kubrick", 1968 );

@Before
public void init() {
inTransaction( session -> session.persist( originalMovie ) );
}

@After
public void tearDown() {
inTransaction( session -> {
Object entity = session.get( Movie.class, originalMovie.getId() );
if ( entity != null ) {
session.delete( entity );
}
} );
}

@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Movie.class };
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* 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.mongodb.test.query.nativequery;

import static org.fest.assertions.Assertions.assertThat;

import java.util.List;

import org.hibernate.ogm.backendtck.queries.projection.Movie;
import org.hibernate.ogm.backendtck.queries.projection.NativeQueryProjectionBaseTest;

import org.junit.Test;

/**
* Use of a projection in MongoDB native query:
* if a projection is used on root Entity then the result must be an Object array instead of an Entity.
*
* addEntity native query parameter is not allowed then projection is used on root Entity.
*
* @author Fabio Massimo Ercoli
*/
public class MongoDBProjectionTest extends NativeQueryProjectionBaseTest {

@Override
protected String getNativeQueryWithoutProjection() {
return "db.Movie.find( {} )";
}

@Override
protected String getNativeQueryWithProjectionIdName() {
return "db.Movie.find( {}, { 'id' : 1, 'name' : 1 } )";
}

@Override
protected String getNativeQueryWithProjectionYearAuthor() {
return "db.Movie.find( {}, { 'year' : 1, 'author' : 1 } )";
}

@Test
public void testResultListWithoutAddEntityWithProjection() {
inTransaction( session -> {
List<Movie> movies = session.createNativeQuery( getNativeQueryWithProjectionYearAuthor() )
.getResultList();

assertThat( movies.get( 0 ) ).isEqualTo( new Object[] { 1, 1968, "Stanley Kubrick" } );
} );
}
}

0 comments on commit de7c199

Please sign in to comment.