Skip to content

Commit 07cad23

Browse files
committed
Merge pull request #333 from arjantijms/master
JPA test for aggregate functions in select clause
2 parents b925063 + f503dc7 commit 07cad23

File tree

8 files changed

+250
-2
lines changed

8 files changed

+250
-2
lines changed
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<parent>
6+
<groupId>org.javaee7</groupId>
7+
<artifactId>jpa</artifactId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
<artifactId>jpa-aggregate-function-in-select</artifactId>
11+
<packaging>war</packaging>
12+
13+
<name>Java EE 7 Sample: jpa - aggregate-function-in-select</name>
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>org.hsqldb</groupId>
18+
<artifactId>hsqldb</artifactId>
19+
<version>2.3.3</version>
20+
</dependency>
21+
</dependencies>
22+
23+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.javaee7.jpa.aggregate_function_in_select.entity;
2+
3+
/**
4+
* A very simple DTO that will be used to aggregate TestEnity to
5+
*
6+
* @author Arjan Tijms
7+
*
8+
*/
9+
public class AggregatedTestEntity {
10+
11+
private String values;
12+
13+
public AggregatedTestEntity(String values) {
14+
this.values = values;
15+
}
16+
17+
public String getValues() {
18+
return values;
19+
}
20+
21+
public void setValues(String values) {
22+
this.values = values;
23+
}
24+
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package org.javaee7.jpa.aggregate_function_in_select.entity;
2+
3+
import static javax.persistence.GenerationType.IDENTITY;
4+
5+
import javax.persistence.Entity;
6+
import javax.persistence.GeneratedValue;
7+
import javax.persistence.Id;
8+
9+
/**
10+
* A very simple JPA entity that will be used for testing
11+
*
12+
* @author Arjan Tijms
13+
*
14+
*/
15+
@Entity
16+
public class TestEntity {
17+
18+
@Id
19+
@GeneratedValue(strategy = IDENTITY)
20+
private Long id;
21+
private String value;
22+
23+
public Long getId() {
24+
return id;
25+
}
26+
27+
public void setId(Long id) {
28+
this.id = id;
29+
}
30+
31+
public String getValue() {
32+
return value;
33+
}
34+
35+
public void setValue(String value) {
36+
this.value = value;
37+
}
38+
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package org.javaee7.jpa.aggregate_function_in_select.service;
2+
3+
import java.util.List;
4+
5+
import javax.ejb.Stateless;
6+
import javax.persistence.EntityManager;
7+
import javax.persistence.PersistenceContext;
8+
9+
import org.javaee7.jpa.aggregate_function_in_select.entity.AggregatedTestEntity;
10+
import org.javaee7.jpa.aggregate_function_in_select.entity.TestEntity;
11+
12+
/**
13+
* This service contains methods to insert two test entities into the database
14+
* and to get the aggregation of those.
15+
*
16+
* @author Arjan Tijms
17+
*
18+
*/
19+
@Stateless
20+
public class TestService {
21+
22+
@PersistenceContext
23+
private EntityManager entityManager;
24+
25+
public void saveEntities() {
26+
27+
TestEntity testEntity1 = new TestEntity();
28+
testEntity1.setValue("1");
29+
TestEntity testEntity2 = new TestEntity();
30+
testEntity2.setValue("2");
31+
32+
entityManager.persist(testEntity1);
33+
entityManager.persist(testEntity2);
34+
}
35+
36+
public List<AggregatedTestEntity> getAggregation() {
37+
return entityManager
38+
.createQuery(
39+
// Note that GROUP_CONCAT is a DB specific function, in this
40+
// case for HSQLDB.
41+
"SELECT new org.javaee7.jpa.aggregate_function_in_select.entity.AggregatedTestEntity("
42+
+ "FUNCTION('GROUP_CONCAT', _testEntity.value)"
43+
+") "
44+
+"FROM "
45+
+ "TestEntity _testEntity ",
46+
AggregatedTestEntity.class
47+
).getResultList();
48+
}
49+
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
4+
5+
<persistence-unit name="testPU">
6+
7+
<!-- This data source is defined from within the application via the data-source element in web.xml -->
8+
<jta-data-source>java:app/MyApp/MyDS</jta-data-source>
9+
10+
<properties>
11+
<!--
12+
Very unfortunate workaround to get the data source to work with JPA in WildFly 8+.
13+
See https://issues.jboss.org/browse/WFLY-2727
14+
-->
15+
<property name="wildfly.jpa.twophasebootstrap" value="false" />
16+
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create" />
17+
</properties>
18+
</persistence-unit>
19+
20+
</persistence>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
4+
5+
<!--
6+
This defines the data source that's used by persistence.xml to back to the JPA persistence unit.
7+
The database is embedded within this application (see the pom.xml of this project).
8+
-->
9+
10+
<data-source>
11+
<name>java:app/MyApp/MyDS</name>
12+
<!-- org.hsqldb.jdbc.JDBCDataSource is non-XA alternative -->
13+
<class-name>org.hsqldb.jdbc.pool.JDBCXADataSource</class-name>
14+
<url>jdbc:hsqldb:mem:realtime;user=test;password=testx</url>
15+
</data-source>
16+
17+
</web-app>
18+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package org.javaee7.jpa.aggregate_function_in_select;
2+
3+
import static org.junit.Assert.assertTrue;
4+
5+
import java.io.File;
6+
import java.util.List;
7+
8+
import javax.inject.Inject;
9+
10+
import org.javaee7.jpa.aggregate_function_in_select.entity.AggregatedTestEntity;
11+
import org.javaee7.jpa.aggregate_function_in_select.service.TestService;
12+
import org.jboss.arquillian.container.test.api.Deployment;
13+
import org.jboss.arquillian.junit.Arquillian;
14+
import org.jboss.shrinkwrap.api.Archive;
15+
import org.jboss.shrinkwrap.api.ShrinkWrap;
16+
import org.jboss.shrinkwrap.api.spec.WebArchive;
17+
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
18+
import org.junit.Test;
19+
import org.junit.runner.RunWith;
20+
21+
/**
22+
* This tests that an aggregate function can be used in the select clause
23+
* <p>
24+
* Currently the JPQL constructor expression is tested for this.
25+
*
26+
* @author Arjan Tijms
27+
*/
28+
@RunWith(Arquillian.class)
29+
public class AggregateFunctionInSelectTest {
30+
31+
private static final String WEBAPP_SRC = "src/main/webapp";
32+
33+
@Inject
34+
private TestService testService;
35+
36+
@Deployment
37+
public static Archive<?> deploy() {
38+
return ShrinkWrap.create(WebArchive.class)
39+
.addPackages(true, AggregateFunctionInSelectTest.class.getPackage())
40+
.addAsResource("META-INF/persistence.xml")
41+
.addAsWebInfResource(resource("web.xml"))
42+
.addAsLibraries(Maven.resolver()
43+
.loadPomFromFile("pom.xml")
44+
.resolve("org.hsqldb:hsqldb")
45+
.withoutTransitivity()
46+
.asSingleFile());
47+
}
48+
49+
@Test
50+
public void aggregateFunctionInCtorSelectJPQL() throws Exception {
51+
52+
testService.saveEntities();
53+
54+
List<AggregatedTestEntity> testEntities = testService.getAggregation();
55+
56+
assertTrue(
57+
"All entities should have been aggregated into 1 result row",
58+
testEntities.size() == 1
59+
);
60+
61+
String values = testEntities.get(0).getValues();
62+
63+
assertTrue(
64+
"Aggregation should be 1,2 or 2,1, but was: " + values,
65+
values.equals("1,2") || values.equals("2,1") // order doesn't matter here
66+
);
67+
}
68+
69+
private static File resource(String name) {
70+
return new File(WEBAPP_SRC + "/WEB-INF", name);
71+
}
72+
}

jpa/pom.xml

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
<version>1.0-SNAPSHOT</version>
99
<relativePath>../pom.xml</relativePath>
1010
</parent>
11-
<groupId>org.javaee7</groupId>
11+
1212
<artifactId>jpa</artifactId>
13-
<version>1.0-SNAPSHOT</version>
1413
<packaging>pom</packaging>
14+
1515
<name>Java EE 7 Sample: jpa</name>
1616

1717
<modules>
18+
<module>aggregate-function-in-select</module>
1819
<module>criteria</module>
1920
<module>datasourcedefinition</module>
2021
<module>datasourcedefinition-webxml-pu</module>

0 commit comments

Comments
 (0)