Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Check how Criteria API behaves with literals
- Loading branch information
1 parent
080d65d
commit 02b234a
Showing
1 changed file
with
216 additions
and
0 deletions.
There are no files selected for viewing
216 changes: 216 additions & 0 deletions
216
...e-core/src/test/java/org/hibernate/jpa/test/criteria/nulliteral/CriteriaLiteralsTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
/* | ||
* Hibernate, Relational Persistence for Idiomatic Java | ||
* | ||
* 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.jpa.test.criteria.nulliteral; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Map; | ||
import javax.persistence.CascadeType; | ||
import javax.persistence.Entity; | ||
import javax.persistence.GeneratedValue; | ||
import javax.persistence.Id; | ||
import javax.persistence.ManyToOne; | ||
import javax.persistence.OneToMany; | ||
import javax.persistence.OrderColumn; | ||
import javax.persistence.Tuple; | ||
import javax.persistence.criteria.CriteriaBuilder; | ||
import javax.persistence.criteria.CriteriaQuery; | ||
import javax.persistence.criteria.ListJoin; | ||
import javax.persistence.criteria.Root; | ||
|
||
import org.hibernate.dialect.H2Dialect; | ||
import org.hibernate.exception.SQLGrammarException; | ||
import org.hibernate.hql.internal.ast.QuerySyntaxException; | ||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; | ||
|
||
import org.hibernate.testing.RequiresDialect; | ||
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; | ||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertNotNull; | ||
import static org.junit.Assert.assertTrue; | ||
import static org.junit.Assert.fail; | ||
|
||
/** | ||
* @author Vlad Mihalcea | ||
*/ | ||
@RequiresDialect(H2Dialect.class) | ||
public class CriteriaLiteralsTest extends BaseEntityManagerFunctionalTestCase { | ||
|
||
private PreparedStatementSpyConnectionProvider connectionProvider = new PreparedStatementSpyConnectionProvider(); | ||
|
||
@Override | ||
protected Map getConfig() { | ||
Map config = super.getConfig(); | ||
config.put( | ||
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER, | ||
connectionProvider | ||
); | ||
return config; | ||
} | ||
|
||
@Override | ||
public void releaseResources() { | ||
super.releaseResources(); | ||
connectionProvider.stop(); | ||
} | ||
|
||
@Override | ||
protected Class<?>[] getAnnotatedClasses() { | ||
return new Class[] { Book.class, Author.class }; | ||
} | ||
|
||
@Before | ||
public void init() { | ||
doInJPA( this::entityManagerFactory, entityManager -> { | ||
Book book = new Book(); | ||
book.name = "Java Persistence with Hibernate"; | ||
|
||
Author author1 = new Author(); | ||
author1.name = "Christian Bauer"; | ||
|
||
Author author2 = new Author(); | ||
author1.name = "Gavin Ling"; | ||
|
||
book.authors.add( author1 ); | ||
book.authors.add( author2 ); | ||
entityManager.persist( book ); | ||
} ); | ||
try { | ||
doInJPA( this::entityManagerFactory, entityManager -> { | ||
entityManager | ||
.createNativeQuery( | ||
"SELECT REPEAT('abc' || ' ', 1000000000000) FROM MY_ENTITY" ) | ||
.getSingleResult(); | ||
} ); | ||
fail( "Should have thrown exception!" ); | ||
} | ||
catch ( Exception expected ) { | ||
assertEquals( | ||
SQLGrammarException.class, | ||
expected.getCause().getClass() | ||
); | ||
} | ||
} | ||
|
||
@Test | ||
public void testLiteralsInWhereClause() throws Exception { | ||
|
||
doInJPA( this::entityManagerFactory, entityManager -> { | ||
|
||
final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); | ||
|
||
final CriteriaQuery<Tuple> query = cb.createQuery( Tuple.class ); | ||
|
||
final Root<Book> entity = query.from( Book.class ); | ||
query.where( cb.equal( | ||
entity.get( "name" ), | ||
cb.literal( | ||
"( SELECT REPEAT('abc' || ' ', 10000000000 FROM MY_ENTITY )" ) | ||
) ); | ||
|
||
query.multiselect( | ||
cb.literal( "abc" ), | ||
entity.get( "name" ) | ||
); | ||
|
||
connectionProvider.clear(); | ||
List<Tuple> tuples = entityManager.createQuery( query ) | ||
.getResultList(); | ||
|
||
assertEquals( | ||
1, | ||
connectionProvider.getPreparedStatements().size() | ||
); | ||
assertNotNull( connectionProvider.getPreparedStatement( | ||
"select 'abc' as col_0_0_, criteriali0_.name as col_1_0_ from Book criteriali0_ where criteriali0_.name=?" ) ); | ||
assertTrue( tuples.isEmpty() ); | ||
} ); | ||
} | ||
|
||
@Test | ||
public void testCriteriaParameters() throws Exception { | ||
doInJPA( this::entityManagerFactory, entityManager -> { | ||
final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); | ||
CriteriaQuery<String> query = cb.createQuery( String.class ); | ||
Root<Book> root = query.from( Book.class ); | ||
ListJoin<Book, Author> authors = root.joinList( "authors" ); | ||
|
||
query.where( cb.equal( | ||
root.get( "name" ), | ||
"( SELECT REPEAT('abc' || ' ', 10000000000 FROM MY_ENTITY )" | ||
), cb.equal( authors.index(), 0 ) ) | ||
.select( authors.get( "name" ) ); | ||
|
||
connectionProvider.clear(); | ||
entityManager.createQuery( query ).getResultList(); | ||
assertEquals( | ||
1, | ||
connectionProvider.getPreparedStatements().size() | ||
); | ||
assertNotNull( connectionProvider.getPreparedStatement( | ||
"select authors1_.name as col_0_0_ from Book criteriali0_ inner join Author authors1_ on criteriali0_.id=authors1_.book_id where criteriali0_.name=? and authors1_.index_id=0" ) | ||
); | ||
} ); | ||
} | ||
|
||
@Test | ||
public void testLiteralsInSelectClause() throws Exception { | ||
try { | ||
doInJPA( this::entityManagerFactory, entityManager -> { | ||
final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); | ||
CriteriaQuery<String> query = cb.createQuery( String.class ); | ||
Root<Book> root = query.from( Book.class ); | ||
ListJoin<Book, Author> authors = root.joinList( "authors" ); | ||
|
||
query.where( cb.equal( | ||
root.get( "name" ), | ||
"Java Persistence with Hibernate" | ||
)) | ||
.select( cb.literal( "( SELECT REPEAT('abc' || ' ', 10000000000 FROM MY_ENTITY )" ) ); | ||
|
||
entityManager.createQuery( query ).getResultList(); | ||
} ); | ||
} | ||
catch ( Exception expected ) { | ||
assertEquals( | ||
QuerySyntaxException.class, | ||
expected.getCause().getClass() | ||
); | ||
} | ||
} | ||
|
||
@Entity(name = "Book") | ||
public static class Book { | ||
|
||
@Id | ||
@GeneratedValue | ||
private Integer id; | ||
|
||
private String name; | ||
|
||
@OneToMany(mappedBy = "book", cascade = CascadeType.ALL) | ||
@OrderColumn(name = "index_id") | ||
private List<Author> authors = new ArrayList<>(); | ||
} | ||
|
||
@Entity(name = "Author") | ||
public static class Author { | ||
|
||
@Id | ||
@GeneratedValue | ||
private Integer id; | ||
|
||
private String name; | ||
|
||
@ManyToOne | ||
private Book book; | ||
} | ||
} |