Kohei Nozaki's blog 

Entries tagged [jpa]

Arquillian Persistence Extension examples


Posted on Wednesday Mar 18, 2015 at 05:47PM in Arquillian


The whole project can be obtained from GitHub. tested with WildFly 8.2.0.Final as remote container.

Implementation (test target)

Assume we have very simple 2 entities as follows:

@Entity
public class Dept implements Serializable {
    @Id
    private Integer id;
    @Column(nullable = false)
    private String name;
    @OneToMany(mappedBy = "dept")
    private Collection<Employee> employees;
...

@Entity
public class Employee implements Serializable {
    @Id
    private Integer id;
    @Column(nullable = false)
    private String name;
    @JoinColumn(nullable = false)
    @ManyToOne
    private Dept dept;
...

Test target EJB:

@Stateless
@LocalBean
public class HumanResourcesBean {

    @PersistenceContext
    private EntityManager em;

    public void addEmployee(Employee employee, Integer deptId) {
        final Dept dept = em.find(Dept.class, deptId);
        dept.getEmployees().add(employee);
        employee.setDept(dept);
        em.persist(employee);
    }

    public void addDept(Dept dept, Employee employee) {
        Collection<Employee> employees = new ArrayList<>();
        dept.setEmployees(employees);
        employees.add(employee);
        employee.setDept(dept);
        em.persist(dept);
        em.persist(employee);
    }
}

addEmployee() testing

Test method of addEmployee():

@Test
@UsingDataSet("input.xml")
@ShouldMatchDataSet(value = "addEmployee-expected.xml", orderBy = "id")
public void addEmployeeTest() throws Exception {
    Employee emp = new Employee();
    emp.setId(2002);
    emp.setName("Todd");
    humanResourcesBean.addEmployee(emp, 200);
}

Initial entry data (input.xml):

<dataset>
    <Dept id="100" name="Sales"/>
    <Dept id="200" name="Finance"/>
    <Employee id="1000" name="Scott"  dept_id="100"/>
    <Employee id="1001" name="Martin" dept_id="100"/>
    <Employee id="1002" name="Nick"   dept_id="100"/>
    <Employee id="2000" name="Jordan" dept_id="200"/>
    <Employee id="2001" name="David"  dept_id="200"/>
</dataset>

Expected data (addEmployee-expected.xml):

<dataset>
    <Employee id="1000" name="Scott"  dept_id="100"/>
    <Employee id="1001" name="Martin" dept_id="100"/>
    <Employee id="1002" name="Nick"   dept_id="100"/>
    <Employee id="2000" name="Jordan" dept_id="200"/>
    <Employee id="2001" name="David"  dept_id="200"/>
    <Employee id="2002" name="Todd"   dept_id="200"/> <!-- Newly added -->
</dataset>

addDept() testing

Test method of addDept():

@Test
@UsingDataSet("input.xml")
@ShouldMatchDataSet(value = "addDept-expected.xml", orderBy = "id")
public void addDeptTest() throws Exception {
    Dept dept = new Dept();
    dept.setId(300);
    dept.setName("Engineering");
    Employee emp = new Employee();
    emp.setId(3000);
    emp.setName("Carl");
    humanResourcesBean.addDept(dept, emp);
}

Initial entry data (input.xml) is the same to previous testing.

Expected data (addDept-expected.xml):

<dataset>
    <Dept id="100" name="Sales"/>
    <Dept id="200" name="Finance"/>
    <Dept id="300" name="Engineering"/> <!-- Newly added -->
    <Employee id="1000" name="Scott"  dept_id="100"/>
    <Employee id="1001" name="Martin" dept_id="100"/>
    <Employee id="1002" name="Nick"   dept_id="100"/>
    <Employee id="2000" name="Jordan" dept_id="200"/>
    <Employee id="2001" name="David"  dept_id="200"/>
    <Employee id="3000" name="Carl"   dept_id="300"/> <!-- Newly added -->
</dataset>

It works well with multiple tables.

addDept() testing with DBUnit

Sometimes use of DBUnit directly is useful for complex assertion. in such case you need to care following conditions:

  • If you use JPA, force EntityManager to execute DMLs via invoking em.flush() before assertion

  • Include test data to the Arquillian’s application archive so that DBUnit can load these data on the server side

The XML can be included via addAsResource() method as follows:

@Deployment
public static Archive<?> createDeploymentPackage() {
    final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war")
            .addPackage(Dept.class.getPackage())
            .addClass(HumanResourcesBean.class)
            .addAsResource("datasets/addDept-expected.xml") // to be loaded by DBUnit on the server side
            .addAsResource("test-persistence.xml", "META-INF/persistence.xml");
//        System.out.println(webArchive.toString(true));
    return webArchive;
}

The test method of addDept() and related convenient methods:

@Test
@UsingDataSet("input.xml")
public void addDeptTestWithDbUnit() throws Exception {
    Dept dept = new Dept();
    dept.setId(300);
    dept.setName("Engineering");
    Employee emp = new Employee();
    emp.setId(3000);
    emp.setName("Carl");

    humanResourcesBean.addDept(dept, emp);
    em.flush(); // force JPA to execute DMLs before assertion

    final IDataSet expectedDataSet = getDataSet("/datasets/addDept-expected.xml");
    assertTable(expectedDataSet.getTable("Dept"), "select * from dept order by id");
    assertTable(expectedDataSet.getTable("Employee"), "select * from employee order by id");
}

private static IDataSet getDataSet(String path) throws DataSetException {
    return new FlatXmlDataSetBuilder().build(HumanResourcesBeanIT.class.getResource(path));
}

private void assertTable(ITable expectedTable, String sql) throws SQLException, DatabaseUnitException {
    try (Connection cn = ds.getConnection()) {
        IDatabaseConnection icn = null;
        try {
            icn = new DatabaseConnection(cn);
            final ITable queryTable = icn.createQueryTable(expectedTable.getTableMetaData().getTableName(), sql);
            Assertion.assertEquals(expectedTable, queryTable);
        } finally {
            if (icn != null) {
                icn.close();
            }
        }
    }
}


Using JPA 2.1 AttributeConverter against Java8 LocalDate / LocalDateTime


Posted on Tuesday Mar 17, 2015 at 01:50PM in JPA


I created an example project using https://weblogs.java.net/blog/montanajava/archive/2014/06/17/using-java-8-datetime-classes-jpa which ran on WildFly 8.2.0.Final (Hibernate 4.3.7) and H2 / Apache Derby database.

the whole project can be obtained from https://github.com/lbtc-xxx/jpa21converter .

You don’t need to define any additional configuration in persistence.xml if you use converters in EE environment. it goes like this:

The converter for LocalDate between DATE

@Converter(autoApply = true)
public class MyLocalDateConverter implements AttributeConverter<java.time.LocalDate, java.sql.Date> {

    @Override
    public java.sql.Date convertToDatabaseColumn(java.time.LocalDate attribute) {
        return attribute == null ? null : java.sql.Date.valueOf(attribute);
    }

    @Override
    public java.time.LocalDate convertToEntityAttribute(java.sql.Date dbData) {
        return dbData == null ? null : dbData.toLocalDate();
    }
}

The converter for LocalDateTime between TIMESTAMP

@Converter(autoApply = true)
public class MyLocalDateTimeConverter implements AttributeConverter<java.time.LocalDateTime, java.sql.Timestamp> {

    @Override
    public java.sql.Timestamp convertToDatabaseColumn(java.time.LocalDateTime attribute) {
        return attribute == null ? null : java.sql.Timestamp.valueOf(attribute);
    }

    @Override
    public java.time.LocalDateTime convertToEntityAttribute(java.sql.Timestamp dbData) {
        return dbData == null ? null : dbData.toLocalDateTime();
    }
}

Entity class

@Entity
public class MySimpleTable implements Serializable {
    @Id
    @GeneratedValue
    private Long id;
    private java.time.LocalDateTime someLocalDateTime;
    private java.time.LocalDate someLocalDate;
...

Hibernate produces the DDL against H2 as follows:

create table MySimpleTable (
    id bigint not null,
    someLocalDate date,
    someLocalDateTime timestamp,
    primary key (id)
)

Using converters with @EmbeddedId

Converters doesn’t work with fields that annotated as @Id (see http://stackoverflow.com/questions/28337798/hibernate-fails-to-load-jpa-2-1-converter-when-loaded-with-spring-boot-and-sprin ) but works with @EmbeddedId class.

Entity class:

@Entity
public class MyCompositeKeyTable implements Serializable {
    @EmbeddedId
    private MyCompositeKeyEmbeddable key;
...

Embeddable class:

@Embeddable
public class MyCompositeKeyEmbeddable implements Serializable {
    @Column(nullable = false)
    private java.time.LocalDateTime someLocalDateTime;
    @Column(nullable = false)
    private java.time.LocalDate someLocalDate;
...

Produced DDL:

create table MyCompositeKeyTable (
    someLocalDate date not null,
    someLocalDateTime timestamp not null,
    primary key (someLocalDate, someLocalDateTime)
)


Just try to use 2nd level cache with WildFly and Hibernate


Posted on Wednesday Feb 19, 2014 at 05:30PM in Technology


Just playing with 2nd level cache that mentioned at [1]. it is a good tutorial so may we only need to refer [1], and this is my notes and logs only.

Environment

  • WildFly 8.0.0.Final (Hibernate 4.3.1)
  • Maven 3.1.1
  • Oracle JDK7u51
  • OS X 10.9.1

Run Maven to get the sample project

kyle-no-MacBook:l2cache kyle$ mvn archetype:generate \
>     -DarchetypeArtifactId=jboss-javaee6-webapp-archetype \
>     -DarchetypeGroupId=org.jboss.spec.archetypes \
>     -DarchetypeVersion=7.1.2.Final \
>     -DgroupId=de.consol.research \
>     -DartifactId=infinispan-jpa-example \
>     -Dversion=1.0-SNAPSHOT \
>     -Dname="Infinispan JPA Example" \
>     -DarchetypeCatalog=http://search.maven.org/remotecontent?filepath=archetype-catalog.xml \
>     -DinteractiveMode=false
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
[INFO] Scanning for projects...
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-install-plugin/2.4/maven-install-plugin-2.4.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-install-plugin/2.4/maven-install-plugin-2.4.pom (7 KB at 5.4 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-deploy-plugin/2.7/maven-deploy-plugin-2.7.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-deploy-plugin/2.7/maven-deploy-plugin-2.7.pom (6 KB at 20.5 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-site-plugin/3.3/maven-site-plugin-3.3.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-site-plugin/3.3/maven-site-plugin-3.3.pom (21 KB at 51.1 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-site-plugin/3.3/maven-site-plugin-3.3.jar
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-site-plugin/3.3/maven-site-plugin-3.3.jar (122 KB at 180.7 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/1.3/maven-antrun-plugin-1.3.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/1.3/maven-antrun-plugin-1.3.pom (5 KB at 17.0 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/1.3/maven-antrun-plugin-1.3.jar
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/1.3/maven-antrun-plugin-1.3.jar (24 KB at 84.3 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/2.2-beta-5/maven-assembly-plugin-2.2-beta-5.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/2.2-beta-5/maven-assembly-plugin-2.2-beta-5.pom (15 KB at 55.4 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/16/maven-plugins-16.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/16/maven-plugins-16.pom (13 KB at 47.0 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/2.2-beta-5/maven-assembly-plugin-2.2-beta-5.jar
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/2.2-beta-5/maven-assembly-plugin-2.2-beta-5.jar (204 KB at 357.8 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/2.8/maven-dependency-plugin-2.8.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/2.8/maven-dependency-plugin-2.8.pom (12 KB at 41.7 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/2.8/maven-dependency-plugin-2.8.jar
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/2.8/maven-dependency-plugin-2.8.jar (150 KB at 274.5 KB/sec)
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom >>>
[INFO] 
[INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom <<<
[INFO] 
[INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom ---
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/reporting/maven-reporting-api/2.0.8/maven-reporting-api-2.0.8.jar
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/doxia/doxia-sink-api/1.0-alpha-9/doxia-sink-api-1.0-alpha-9.jar
Downloading: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-interactivity-api/1.0-alpha-5/plexus-interactivity-api-1.0-alpha-5.jar
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/reporting/maven-reporting-api/2.0.8/maven-reporting-api-2.0.8.jar (10 KB at 28.5 KB/sec)
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/doxia/doxia-sink-api/1.0-alpha-9/doxia-sink-api-1.0-alpha-9.jar (10 KB at 19.8 KB/sec)
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-interactivity-api/1.0-alpha-5/plexus-interactivity-api-1.0-alpha-5.jar (14 KB at 26.0 KB/sec)
[INFO] Generating project in Batch mode
[INFO] Archetype repository missing. Using the one from [org.jboss.spec.archetypes:jboss-javaee6-webapp-archetype:7.1.3.Final] found in catalog http://search.maven.org/remotecontent?filepath=archetype-catalog.xml
Downloading: http://search.maven.org/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.jar
Downloading: http://repo.maven.apache.org/maven2/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.jar
Downloaded: http://repo.maven.apache.org/maven2/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.jar (96 KB at 88.0 KB/sec)
Downloading: http://search.maven.org/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.pom
Downloading: http://repo.maven.apache.org/maven2/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.pom
Downloaded: http://repo.maven.apache.org/maven2/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.pom (3 KB at 5.5 KB/sec)
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: jboss-javaee6-webapp-archetype:7.1.2.Final
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: de.consol.research
[INFO] Parameter: artifactId, Value: infinispan-jpa-example
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: de.consol.research
[INFO] Parameter: packageInPathFormat, Value: de/consol/research
[INFO] Parameter: package, Value: de.consol.research
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: name, Value: Infinispan JPA Example
[INFO] Parameter: groupId, Value: de.consol.research
[INFO] Parameter: jboss-bom-enterprise-version, Value: 1.0.4.Final-redhat-1
[INFO] Parameter: artifactId, Value: infinispan-jpa-example
[INFO] Parameter: enterprise, Value: false
[INFO] project created from Archetype in dir: /Users/kyle/src/l2cache/infinispan-jpa-example
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 18.514s
[INFO] Finished at: Wed Feb 19 17:26:26 JST 2014
[INFO] Final Memory: 14M/245M
[INFO] ------------------------------------------------------------------------

Import the project to Eclipse

  • File - Import - Existing Maven Projects
  • It comes with no errors.

Make the application to use PostgreSQL

This is not necessary for everyone. It comes with internal H2 datasource definition in the application so we can just skip this work.

Create a database

jbatch=# create database infinispan owner kyle encoding 'UTF8' TEMPLATE template0;
CREATE DATABASE
jbatch=# 

Define a data source

data-source add \
 --name=InfinispanExampleDS \
 --driver-name=postgresql \
 --connection-url=jdbc:postgresql://localhost:5432/infinispan \
 --jndi-name=java:jboss/datasources/infinispan-jpa-exampleDS \
 --user-name=postgres \
 --password=***

Delete datasource definition in WEB-INF

delete Deployed Resources/webapp/WEB-INF/infinispan-jpa-example-ds.xml

Deploy

I did it with Eclipse.

  1. Open Servers Window
  2. Right-click WildFly
  3. Add and remove
  4. Add infinispan-jpa-example
  5. Finish

Browse JSF page

  • Browse here
  • When we reload the page, every time it executes SELECT clause. like this:
17:46:37,631 DEBUG [org.hibernate.SQL] (default task-11) select member0_.id as id1_0_, member0_.email as email2_0_, member0_.name as name3_0_, member0_.phone_number as phone_nu4_0_ from Member member0_ order by member0_.name asc
17:46:39,055 DEBUG [org.hibernate.SQL] (default task-12) select member0_.id as id1_0_, member0_.email as email2_0_, member0_.name as name3_0_, member0_.phone_number as phone_nu4_0_ from Member member0_ order by member0_.name asc
17:49:13,527 DEBUG [org.hibernate.SQL] (default task-10) select member0_.id as id1_0_, member0_.email as email2_0_, member0_.name as name3_0_, member0_.phone_number as phone_nu4_0_ from Member member0_ order by member0_.name asc
  • One test data is already registered when we browse the page.

Send GET request

kyle-no-MacBook:infinispan-jpa-example kyle$ curl http://localhost:8080/infinispan-jpa-example/rest/members/0 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><member><email>john.smith@mailinator.com</email><id>0</id><name>John Smith</name><phoneNumber>2125551212</phoneNumber></member>kyle-no-MacBook:infinispan-jpa-example kyle$ 

It executes SQL for every request.

17:55:28,664 DEBUG [org.hibernate.SQL] (default task-6) select member0_.id as id1_0_0_, member0_.email as email2_0_0_, member0_.name as name3_0_0_, member0_.phone_number as phone_nu4_0_0_ from Member member0_ where member0_.id=?
17:55:28,665 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [1] as [BIGINT] - [0]

Modify persistence.xml to use l2-cache

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
   xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
        http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
   <persistence-unit name="primary">
      <!-- If you are running in a production environment, add a managed 
         data source, the example data source is just for development and testing! -->
      <jta-data-source>java:jboss/datasources/infinispan-jpa-exampleDS</jta-data-source>
      <shared-cache-mode>DISABLE_SELECTIVE</shared-cache-mode>
      <properties>
         <!-- Properties for Hibernate -->
         <property name="hibernate.hbm2ddl.auto" value="create-drop" />
         <property name="hibernate.show_sql" value="false" />
         <property name="hibernate.cache.use_second_level_cache" value="true"/>
      </properties>
   </persistence-unit>
</persistence>

Send GET request again

  • Now SQL is executed only once.

Browse JSF page again

  • It still executes SQL every time I reload. why?

Make the application to allow to use l2-cache for queries

In reference to [2], we still have to modify some codes.

Modify persistence.xml

Add this property:

         <property name="hibernate.cache.use_query_cache" value="true" />

Now it is:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
   xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
        http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
   <persistence-unit name="primary">
      <!-- If you are running in a production environment, add a managed 
         data source, the example data source is just for development and testing! -->
      <jta-data-source>java:jboss/datasources/infinispan-jpa-exampleDS</jta-data-source>
      <shared-cache-mode>DISABLE_SELECTIVE</shared-cache-mode>
      <properties>
         <!-- Properties for Hibernate -->
         <property name="hibernate.hbm2ddl.auto" value="create-drop" />
         <property name="hibernate.show_sql" value="false" />
         <property name="hibernate.cache.use_second_level_cache" value="true"/>
         <property name="hibernate.cache.use_query_cache" value="true" />
      </properties>
   </persistence-unit>
</persistence>

Modify the code of JSF page

The query is executed in MemberListProducer#retrieveAllMembersOrderedByName():

   @PostConstruct
   public void retrieveAllMembersOrderedByName() {
      CriteriaBuilder cb = em.getCriteriaBuilder();
      CriteriaQuery<Member> criteria = cb.createQuery(Member.class);
      Root<Member> member = criteria.from(Member.class);
      // Swap criteria statements if you would like to try out type-safe criteria queries, a new
      // feature in JPA 2.0
      // criteria.select(member).orderBy(cb.asc(member.get(Member_.name)));
      criteria.select(member).orderBy(cb.asc(member.get("name")));
      members = em.createQuery(criteria).getResultList();
   }

Add the code that invokes Query#setHint():

setHint("org.hibernate.cacheable", true)

Now the code is:

   @PostConstruct
   public void retrieveAllMembersOrderedByName() {
       CriteriaBuilder cb = em.getCriteriaBuilder();
       CriteriaQuery<Member> criteria = cb.createQuery(Member.class);
       Root<Member> member = criteria.from(Member.class);
       // Swap criteria statements if you would like to try out type-safe criteria queries, a new
       // feature in JPA 2.0
       // criteria.select(member).orderBy(cb.asc(member.get(Member_.name)));
       criteria.select(member).orderBy(cb.asc(member.get("name")));
       members = em.createQuery(criteria).setHint("org.hibernate.cacheable", true).getResultList();
   }

Browse JSF page once again

  • Now SQL is executed only once even I reloaded many times.

Remarks

  • As default, 2nd level cache is disabled for queries.
    • It seems enabled for operations like EntityManager#find() only.
    • Every time queries need to set hint “org.hibernate.cacheable=true”.
  • According to [3], it seems to there is a way to avoid to invoke annoying setHint() method for every queries.
    • Seems to Query Hints are can define at when we declare Named Query.
    • May I would try it later.

References

  1. Infinispan JPA 2nd Level Caching on JBoss AS 7 – Minimal Working Example – ConSol* Labs
  2. JPAのSecond Level Cacheを試してみる - Starlight
  3. 4.2.3. Query result caching


Just try to use ElementCollection with List


Posted on Tuesday Feb 18, 2014 at 02:45PM in Technology


As I tried in Just try to use ElementCollection with Set, this is for Lists.

Environment

  • WildFly 8.0.0.Final
  • Hibernate 4.3.1
  • PostgreSQL 9.2.4
  • postgresql-9.3-1100.jdbc41.jar

Example project

Whole project resources are available in GitHub.

Ordering of elements

  • According to the spec, ordering of elements will not be kept by JPA as default.
  • It can be achieved easily with @OrderBy or @OrderColumn.
    • Now It works for ElementCollection with basic type at recent versions of Hibernate[1].

List<Basic> with @OrderBy

Schema

jpatest=# \d listbasicorderby
Table "public.listbasicorderby"
 Column |  Type  | Modifiers 
--------+--------+-----------
 id     | bigint | not null
Indexes:
    "listbasicorderby_pkey" PRIMARY KEY, btree (id)
Referenced by:
    TABLE "listbasicorderby_list" CONSTRAINT "fk_5fs67i9n98xsp58x8vp4myxq8" FOREIGN KEY (listbasicorderby_id) REFERENCES listbasicorderby(id)

jpatest=# \d listbasicorderby_list 
           Table "public.listbasicorderby_list"
       Column        |          Type          | Modifiers 
---------------------+------------------------+-----------
 listbasicorderby_id | bigint                 | not null
 list                | character varying(255) | 
Foreign-key constraints:
    "fk_5fs67i9n98xsp58x8vp4myxq8" FOREIGN KEY (listbasicorderby_id) REFERENCES listbasicorderby(id)

jpatest=# 

Entry data

log

15:42:35,481 DEBUG [org.hibernate.SQL] (default task-6) insert into ListBasicOrderBy (id) values (?)
15:42:35,481 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [1] as [BIGINT] - [1]
15:42:35,482 DEBUG [org.hibernate.SQL] (default task-6) insert into ListBasicOrderBy_list (ListBasicOrderBy_id, list) values (?, ?)
15:42:35,482 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [1] as [BIGINT] - [1]
15:42:35,482 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [2] as [VARCHAR] - [hoge]
15:42:35,484 DEBUG [org.hibernate.SQL] (default task-6) insert into ListBasicOrderBy_list (ListBasicOrderBy_id, list) values (?, ?)
15:42:35,484 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [1] as [BIGINT] - [1]
15:42:35,484 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [2] as [VARCHAR] - [hoge]
15:42:35,484 DEBUG [org.hibernate.SQL] (default task-6) insert into ListBasicOrderBy_list (ListBasicOrderBy_id, list) values (?, ?)
15:42:35,484 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [1] as [BIGINT] - [1]
15:42:35,484 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [2] as [VARCHAR] - [hige]

table

jpatest=# select * from listbasicorderby;
 id 
----
  1
(1 row)

jpatest=# select * from listbasicorderby_list order by list;
 listbasicorderby_id | list 
---------------------+------
                   1 | hige
                   1 | hoge
                   1 | hoge
(3 rows)

Find

15:58:19,719 DEBUG [org.hibernate.SQL] (default task-15) select listbasico0_.id as id1_0_0_ from ListBasicOrderBy listbasico0_ where listbasico0_.id=?
15:58:19,720 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-15) binding parameter [1] as [BIGINT] - [1]
15:58:19,721 DEBUG [org.hibernate.SQL] (default task-15) select list0_.ListBasicOrderBy_id as ListBasi1_0_0_, list0_.list as list2_1_0_ from ListBasicOrderBy_list list0_ where list0_.ListBasicOrderBy_id=? order by list0_.list asc
15:58:19,721 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-15) binding parameter [1] as [BIGINT] - [1]
15:58:19,721 FINE  [org.nailedtothex.jpatest.list.ListBasicTestDataManipulator] (default task-15) find(): [hige, hoge, hoge]

Add

log

16:05:46,474 DEBUG [org.hibernate.SQL] (default task-14) select listbasico0_.id as id1_0_0_ from ListBasicOrderBy listbasico0_ where listbasico0_.id=?
16:05:46,474 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [1] as [BIGINT] - [1]
16:05:46,475 DEBUG [org.hibernate.SQL] (default task-14) select list0_.ListBasicOrderBy_id as ListBasi1_0_0_, list0_.list as list2_1_0_ from ListBasicOrderBy_list list0_ where list0_.ListBasicOrderBy_id=? order by list0_.list asc
16:05:46,476 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [1] as [BIGINT] - [1]
16:05:46,480 DEBUG [org.hibernate.SQL] (default task-14) delete from ListBasicOrderBy_list where ListBasicOrderBy_id=?
16:05:46,480 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [1] as [BIGINT] - [1]
16:05:46,481 DEBUG [org.hibernate.SQL] (default task-14) insert into ListBasicOrderBy_list (ListBasicOrderBy_id, list) values (?, ?)
16:05:46,481 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [1] as [BIGINT] - [1]
16:05:46,481 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [2] as [VARCHAR] - [hige]
16:05:46,481 DEBUG [org.hibernate.SQL] (default task-14) insert into ListBasicOrderBy_list (ListBasicOrderBy_id, list) values (?, ?)
16:05:46,482 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [1] as [BIGINT] - [1]
16:05:46,482 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [2] as [VARCHAR] - [hoge]
16:05:46,482 DEBUG [org.hibernate.SQL] (default task-14) insert into ListBasicOrderBy_list (ListBasicOrderBy_id, list) values (?, ?)
16:05:46,482 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [1] as [BIGINT] - [1]
16:05:46,482 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [2] as [VARCHAR] - [hoge]
16:05:46,483 DEBUG [org.hibernate.SQL] (default task-14) insert into ListBasicOrderBy_list (ListBasicOrderBy_id, list) values (?, ?)
16:05:46,483 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [1] as [BIGINT] - [1]
16:05:46,483 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [2] as [VARCHAR] - [hige]

table

jpatest=# select * from listbasicorderby_list order by list;
 listbasicorderby_id | list 
---------------------+------
                   1 | hige
                   1 | hige
                   1 | hoge
                   1 | hoge
(4 rows)

jpatest=# 
  • Surprisingly, Hibernate deletes all of elements, and insert them again.

Remove

log

16:14:09,474 DEBUG [org.hibernate.SQL] (default task-3) select listbasico0_.id as id1_0_0_ from ListBasicOrderBy listbasico0_ where listbasico0_.id=?
16:14:09,474 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [1] as [BIGINT] - [1]
16:14:09,475 DEBUG [org.hibernate.SQL] (default task-3) select list0_.ListBasicOrderBy_id as ListBasi1_0_0_, list0_.list as list2_1_0_ from ListBasicOrderBy_list list0_ where list0_.ListBasicOrderBy_id=? order by list0_.list asc
16:14:09,475 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [1] as [BIGINT] - [1]
16:14:09,480 DEBUG [org.hibernate.SQL] (default task-3) delete from ListBasicOrderBy_list where ListBasicOrderBy_id=?
16:14:09,480 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [1] as [BIGINT] - [1]
16:14:09,480 DEBUG [org.hibernate.SQL] (default task-3) insert into ListBasicOrderBy_list (ListBasicOrderBy_id, list) values (?, ?)
16:14:09,480 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [1] as [BIGINT] - [1]
16:14:09,480 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [2] as [VARCHAR] - [hige]
16:14:09,481 DEBUG [org.hibernate.SQL] (default task-3) insert into ListBasicOrderBy_list (ListBasicOrderBy_id, list) values (?, ?)
16:14:09,481 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [1] as [BIGINT] - [1]
16:14:09,481 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [2] as [VARCHAR] - [hoge]

table

jpatest=# select * from listbasicorderby_list order by list;
 listbasicorderby_id | list 
---------------------+------
                   1 | hige
                   1 | hoge
(2 rows)

jpatest=# 
  • Hibernate deletes all of elements again, same as preceding try.

List<Basic> with @OrderColumn

Schema

jpatest=# \d listbasicordercolumn
Table "public.listbasicordercolumn"
 Column |  Type  | Modifiers 
--------+--------+-----------
 id     | bigint | not null
Indexes:
    "listbasicordercolumn_pkey" PRIMARY KEY, btree (id)
Referenced by:
    TABLE "listbasicordercolumn_list" CONSTRAINT "fk_rp520yoe4qk3x4joe6114js" FOREIGN KEY (listbasicordercolumn_id) REFERENCES listbasicordercolumn(id)

jpatest=# \d listbasicordercolumn_list
           Table "public.listbasicordercolumn_list"
         Column          |          Type          | Modifiers 
-------------------------+------------------------+-----------
 listbasicordercolumn_id | bigint                 | not null
 list                    | character varying(255) | 
 list_order              | integer                | not null
Indexes:
    "listbasicordercolumn_list_pkey" PRIMARY KEY, btree (listbasicordercolumn_id, list_order)
Foreign-key constraints:
    "fk_rp520yoe4qk3x4joe6114js" FOREIGN KEY (listbasicordercolumn_id) REFERENCES listbasicordercolumn(id)

Entry data

log

16:29:32,747 DEBUG [org.hibernate.SQL] (default task-2) insert into ListBasicOrderColumn (id) values (?)
16:29:32,748 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-2) binding parameter [1] as [BIGINT] - [1]
16:29:32,749 DEBUG [org.hibernate.SQL] (default task-2) insert into ListBasicOrderColumn_list (ListBasicOrderColumn_id, list_ORDER, list) values (?, ?, ?)
16:29:32,749 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-2) binding parameter [1] as [BIGINT] - [1]
16:29:32,749 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-2) binding parameter [2] as [INTEGER] - [0]
16:29:32,749 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-2) binding parameter [3] as [VARCHAR] - [hoge]
16:29:32,750 DEBUG [org.hibernate.SQL] (default task-2) insert into ListBasicOrderColumn_list (ListBasicOrderColumn_id, list_ORDER, list) values (?, ?, ?)
16:29:32,750 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-2) binding parameter [1] as [BIGINT] - [1]
16:29:32,751 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-2) binding parameter [2] as [INTEGER] - [1]
16:29:32,751 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-2) binding parameter [3] as [VARCHAR] - [hoge]
16:29:32,751 DEBUG [org.hibernate.SQL] (default task-2) insert into ListBasicOrderColumn_list (ListBasicOrderColumn_id, list_ORDER, list) values (?, ?, ?)
16:29:32,751 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-2) binding parameter [1] as [BIGINT] - [1]
16:29:32,751 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-2) binding parameter [2] as [INTEGER] - [2]
16:29:32,752 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-2) binding parameter [3] as [VARCHAR] - [hige]

table

jpatest=# select * from listbasicordercolumn;
 id 
----
  1
(1 row)

jpatest=# select * from listbasicordercolumn_list order by list_order;
 listbasicordercolumn_id | list | list_order 
-------------------------+------+------------
                       1 | hoge |          0
                       1 | hoge |          1
                       1 | hige |          2
(3 rows)

jpatest=# 

Find

16:39:29,863 DEBUG [org.hibernate.SQL] (default task-2) select listbasico0_.id as id1_2_0_ from ListBasicOrderColumn listbasico0_ where listbasico0_.id=?
16:39:29,864 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-2) binding parameter [1] as [BIGINT] - [1]
16:39:29,865 DEBUG [org.hibernate.SQL] (default task-2) select list0_.ListBasicOrderColumn_id as ListBasi1_2_0_, list0_.list as list2_3_0_, list0_.list_ORDER as list_ORD3_0_ from ListBasicOrderColumn_list list0_ where list0_.ListBasicOrderColumn_id=?
16:39:29,865 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-2) binding parameter [1] as [BIGINT] - [1]
16:39:29,865 FINE  [org.nailedtothex.jpatest.list.ListBasicOrderColumnTestDataManipulator] (default task-2) find(): [hoge, hoge, hige]
  • List returned with correct order while there is no ORDER BY in the select clause.
  • I guess that every rows have its order number, so they doesn't need to got sorted at database side.

Add

log

16:46:43,469 DEBUG [org.hibernate.SQL] (default task-6) select listbasico0_.id as id1_2_0_ from ListBasicOrderColumn listbasico0_ where listbasico0_.id=?
16:46:43,469 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [1] as [BIGINT] - [1]
16:46:43,470 DEBUG [org.hibernate.SQL] (default task-6) select list0_.ListBasicOrderColumn_id as ListBasi1_2_0_, list0_.list as list2_3_0_, list0_.list_ORDER as list_ORD3_0_ from ListBasicOrderColumn_list list0_ where list0_.ListBasicOrderColumn_id=?
16:46:43,470 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [1] as [BIGINT] - [1]
16:46:43,474 DEBUG [org.hibernate.SQL] (default task-6) update ListBasicOrderColumn_list set list=? where ListBasicOrderColumn_id=? and list_ORDER=?
16:46:43,475 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [1] as [VARCHAR] - [hige]
16:46:43,475 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [2] as [BIGINT] - [1]
16:46:43,475 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [3] as [INTEGER] - [1]
16:46:43,475 DEBUG [org.hibernate.SQL] (default task-6) update ListBasicOrderColumn_list set list=? where ListBasicOrderColumn_id=? and list_ORDER=?
16:46:43,475 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [1] as [VARCHAR] - [hoge]
16:46:43,476 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [2] as [BIGINT] - [1]
16:46:43,476 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [3] as [INTEGER] - [2]
16:46:43,476 DEBUG [org.hibernate.SQL] (default task-6) insert into ListBasicOrderColumn_list (ListBasicOrderColumn_id, list_ORDER, list) values (?, ?, ?)
16:46:43,476 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [1] as [BIGINT] - [1]
16:46:43,476 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [2] as [INTEGER] - [3]
16:46:43,476 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [3] as [VARCHAR] - [hige]

table

jpatest=# select * from listbasicordercolumn_list order by list_order;
 listbasicordercolumn_id | list | list_order 
-------------------------+------+------------
                       1 | hoge |          0
                       1 | hige |          1
                       1 | hoge |          2
                       1 | hige |          3
(4 rows)

jpatest=# 
  • Tried to add a element with index 1, it works correctly.

Remove

log

16:52:52,834 DEBUG [org.hibernate.SQL] (default task-4) select listbasico0_.id as id1_2_0_ from ListBasicOrderColumn listbasico0_ where listbasico0_.id=?
16:52:52,834 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-4) binding parameter [1] as [BIGINT] - [1]
16:52:52,835 DEBUG [org.hibernate.SQL] (default task-4) select list0_.ListBasicOrderColumn_id as ListBasi1_2_0_, list0_.list as list2_3_0_, list0_.list_ORDER as list_ORD3_0_ from ListBasicOrderColumn_list list0_ where list0_.ListBasicOrderColumn_id=?
16:52:52,835 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-4) binding parameter [1] as [BIGINT] - [1]
16:52:52,841 DEBUG [org.hibernate.SQL] (default task-4) delete from ListBasicOrderColumn_list where ListBasicOrderColumn_id=? and list_ORDER=?
16:52:52,841 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-4) binding parameter [1] as [BIGINT] - [1]
16:52:52,841 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-4) binding parameter [2] as [INTEGER] - [2]
16:52:52,842 DEBUG [org.hibernate.SQL] (default task-4) update ListBasicOrderColumn_list set list=? where ListBasicOrderColumn_id=? and list_ORDER=?
16:52:52,842 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-4) binding parameter [1] as [VARCHAR] - [hige]
16:52:52,842 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-4) binding parameter [2] as [BIGINT] - [1]
16:52:52,842 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-4) binding parameter [3] as [INTEGER] - [1]

table

jpatest=# select * from listbasicordercolumn_list order by list_order;
 listbasicordercolumn_id | list | list_order 
-------------------------+------+------------
                       1 | hoge |          0
                       1 | hige |          1
(2 rows)

Swap

log

16:58:05,240 DEBUG [org.hibernate.SQL] (default task-11) select listbasico0_.id as id1_2_0_ from ListBasicOrderColumn listbasico0_ where listbasico0_.id=?
16:58:05,241 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-11) binding parameter [1] as [BIGINT] - [1]
16:58:05,242 DEBUG [org.hibernate.SQL] (default task-11) select list0_.ListBasicOrderColumn_id as ListBasi1_2_0_, list0_.list as list2_3_0_, list0_.list_ORDER as list_ORD3_0_ from ListBasicOrderColumn_list list0_ where list0_.ListBasicOrderColumn_id=?
16:58:05,243 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-11) binding parameter [1] as [BIGINT] - [1]
16:58:05,245 FINE  [org.nailedtothex.jpatest.list.ListBasicOrderColumnTestDataManipulator] (default task-11) swap(): [hige, hoge, hoge]
16:58:05,248 DEBUG [org.hibernate.SQL] (default task-11) update ListBasicOrderColumn_list set list=? where ListBasicOrderColumn_id=? and list_ORDER=?
16:58:05,248 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-11) binding parameter [1] as [VARCHAR] - [hige]
16:58:05,248 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-11) binding parameter [2] as [BIGINT] - [1]
16:58:05,248 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-11) binding parameter [3] as [INTEGER] - [0]
16:58:05,249 DEBUG [org.hibernate.SQL] (default task-11) update ListBasicOrderColumn_list set list=? where ListBasicOrderColumn_id=? and list_ORDER=?
16:58:05,249 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-11) binding parameter [1] as [VARCHAR] - [hoge]
16:58:05,249 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-11) binding parameter [2] as [BIGINT] - [1]
16:58:05,249 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-11) binding parameter [3] as [INTEGER] - [2]

table

jpatest=# select * from listbasicordercolumn_list order by list_order;
 listbasicordercolumn_id | list | list_order 
-------------------------+------+------------
                       1 | hige |          0
                       1 | hoge |          1
                       1 | hoge |          2
(3 rows)

List<Embeddable>

Schema

jpatest=# \d listembeddableparent
Table "public.listembeddableparent"
 Column |  Type  | Modifiers 
--------+--------+-----------
 id     | bigint | not null
Indexes:
    "listembeddableparent_pkey" PRIMARY KEY, btree (id)
Referenced by:
    TABLE "listembeddableparent_listembeddablechilds" CONSTRAINT "fk_owld92ex87wavc8ncap74eqk2" FOREIGN KEY (listembeddableparent_id) REFERENCES listembeddableparent(id)

jpatest=# \d listembeddableparent_listembeddablechilds
    Table "public.listembeddableparent_listembeddablechilds"
           Column           |          Type          | Modifiers 
----------------------------+------------------------+-----------
 listembeddableparent_id    | bigint                 | not null
 embfield1                  | character varying(255) | 
 embfield2                  | character varying(255) | 
 listembeddablechilds_order | integer                | not null
Indexes:
    "listembeddableparent_listembeddablechilds_pkey" PRIMARY KEY, btree (listembeddableparent_id, listembeddablechilds_order)
Foreign-key constraints:
    "fk_owld92ex87wavc8ncap74eqk2" FOREIGN KEY (listembeddableparent_id) REFERENCES listembeddableparent(id)

jpatest=# 

Entry data

log

17:10:16,833 DEBUG [org.hibernate.SQL] (default task-13) insert into ListEmbeddableParent (id) values (?)
17:10:16,834 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [1] as [BIGINT] - [1]
17:10:16,836 DEBUG [org.hibernate.SQL] (default task-13) insert into ListEmbeddableParent_listEmbeddableChilds (ListEmbeddableParent_id, listEmbeddableChilds_ORDER, embField1, embField2) values (?, ?, ?, ?)
17:10:16,836 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [1] as [BIGINT] - [1]
17:10:16,836 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [2] as [INTEGER] - [0]
17:10:16,836 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [3] as [VARCHAR] - [child1field1]
17:10:16,836 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [4] as [VARCHAR] - [child1field2]
17:10:16,840 DEBUG [org.hibernate.SQL] (default task-13) insert into ListEmbeddableParent_listEmbeddableChilds (ListEmbeddableParent_id, listEmbeddableChilds_ORDER, embField1, embField2) values (?, ?, ?, ?)
17:10:16,840 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [1] as [BIGINT] - [1]
17:10:16,840 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [2] as [INTEGER] - [1]
17:10:16,840 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [3] as [VARCHAR] - [child2field1]
17:10:16,840 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [4] as [VARCHAR] - [child2field2]
17:10:16,841 DEBUG [org.hibernate.SQL] (default task-13) insert into ListEmbeddableParent_listEmbeddableChilds (ListEmbeddableParent_id, listEmbeddableChilds_ORDER, embField1, embField2) values (?, ?, ?, ?)
17:10:16,841 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [1] as [BIGINT] - [1]
17:10:16,841 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [2] as [INTEGER] - [2]
17:10:16,842 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [3] as [VARCHAR] - [child3field1]
17:10:16,842 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [4] as [VARCHAR] - [child3field2]

table

jpatest=# select * from listembeddableparent;
 id 
----
  1
(1 row)

jpatest=# select * from listembeddableparent_listembeddablechilds order by listembeddablechilds_order;
 listembeddableparent_id |  embfield1   |  embfield2   | listembeddablechilds_order 
-------------------------+--------------+--------------+----------------------------
                       1 | child1field1 | child1field2 |                          0
                       1 | child2field1 | child2field2 |                          1
                       1 | child3field1 | child3field2 |                          2
(3 rows)

Find

17:32:03,442 DEBUG [org.hibernate.SQL] (default task-7) select listembedd0_.id as id1_4_0_ from ListEmbeddableParent listembedd0_ where listembedd0_.id=?
17:32:03,443 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [1] as [BIGINT] - [1]
17:32:03,444 DEBUG [org.hibernate.SQL] (default task-7) select listembedd0_.ListEmbeddableParent_id as ListEmbe1_4_0_, listembedd0_.embField1 as embField2_5_0_, listembedd0_.embField2 as embField3_5_0_, listembedd0_.listEmbeddableChilds_ORDER as listEmbe4_0_ from ListEmbeddableParent_listEmbeddableChilds listembedd0_ where listembedd0_.ListEmbeddableParent_id=?
17:32:03,444 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [1] as [BIGINT] - [1]
17:32:03,443 FINE  [org.nailedtothex.jpatest.list.ListEmbeddableTestDataManipulator] (default task-7) find(): [ListEmbeddableChild [embField1=child1field1, embField2=child1field2], ListEmbeddableChild [embField1=child2field1, embField2=child2field2], ListEmbeddableChild [embField1=child3field1, embField2=child3field2]]

Add

log

17:42:47,823 DEBUG [org.hibernate.SQL] (default task-3) select listembedd0_.id as id1_4_0_ from ListEmbeddableParent listembedd0_ where listembedd0_.id=?
17:42:47,824 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [1] as [BIGINT] - [1]
17:42:47,825 DEBUG [org.hibernate.SQL] (default task-3) select listembedd0_.ListEmbeddableParent_id as ListEmbe1_4_0_, listembedd0_.embField1 as embField2_5_0_, listembedd0_.embField2 as embField3_5_0_, listembedd0_.listEmbeddableChilds_ORDER as listEmbe4_0_ from ListEmbeddableParent_listEmbeddableChilds listembedd0_ where listembedd0_.ListEmbeddableParent_id=?
17:42:47,826 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [1] as [BIGINT] - [1]
17:42:47,830 DEBUG [org.hibernate.SQL] (default task-3) update ListEmbeddableParent_listEmbeddableChilds set embField1=?, embField2=? where ListEmbeddableParent_id=? and listEmbeddableChilds_ORDER=?
17:42:47,830 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [1] as [VARCHAR] - [child4field1]
17:42:47,830 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [2] as [VARCHAR] - [child4field2]
17:42:47,830 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [3] as [BIGINT] - [1]
17:42:47,830 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [4] as [INTEGER] - [2]
17:42:47,831 DEBUG [org.hibernate.SQL] (default task-3) insert into ListEmbeddableParent_listEmbeddableChilds (ListEmbeddableParent_id, listEmbeddableChilds_ORDER, embField1, embField2) values (?, ?, ?, ?)
17:42:47,831 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [1] as [BIGINT] - [1]
17:42:47,831 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [2] as [INTEGER] - [3]
17:42:47,831 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [3] as [VARCHAR] - [child3field1]
17:42:47,831 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-3) binding parameter [4] as [VARCHAR] - [child3field2]

table

jpatest=# select * from listembeddableparent_listembeddablechilds order by listembeddablechilds_order;
 listembeddableparent_id |  embfield1   |  embfield2   | listembeddablechilds_order 
-------------------------+--------------+--------------+----------------------------
                       1 | child1field1 | child1field2 |                          0
                       1 | child2field1 | child2field2 |                          1
                       1 | child4field1 | child4field2 |                          2
                       1 | child3field1 | child3field2 |                          3
(4 rows)

Remove

log

17:47:20,736 DEBUG [org.hibernate.SQL] (default task-14) select listembedd0_.id as id1_4_0_ from ListEmbeddableParent listembedd0_ where listembedd0_.id=?
17:47:20,737 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [1] as [BIGINT] - [1]
17:47:20,738 DEBUG [org.hibernate.SQL] (default task-14) select listembedd0_.ListEmbeddableParent_id as ListEmbe1_4_0_, listembedd0_.embField1 as embField2_5_0_, listembedd0_.embField2 as embField3_5_0_, listembedd0_.listEmbeddableChilds_ORDER as listEmbe4_0_ from ListEmbeddableParent_listEmbeddableChilds listembedd0_ where listembedd0_.ListEmbeddableParent_id=?
17:47:20,738 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [1] as [BIGINT] - [1]
17:47:20,744 DEBUG [org.hibernate.SQL] (default task-14) delete from ListEmbeddableParent_listEmbeddableChilds where ListEmbeddableParent_id=? and listEmbeddableChilds_ORDER=?
17:47:20,744 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [1] as [BIGINT] - [1]
17:47:20,744 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [2] as [INTEGER] - [2]
17:47:20,745 DEBUG [org.hibernate.SQL] (default task-14) update ListEmbeddableParent_listEmbeddableChilds set embField1=?, embField2=? where ListEmbeddableParent_id=? and listEmbeddableChilds_ORDER=?
17:47:20,745 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [1] as [VARCHAR] - [child3field1]
17:47:20,745 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [2] as [VARCHAR] - [child3field2]
17:47:20,745 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [3] as [BIGINT] - [1]
17:47:20,745 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [4] as [INTEGER] - [1]

table

jpatest=# select * from listembeddableparent_listembeddablechilds order by listembeddablechilds_order;
 listembeddableparent_id |  embfield1   |  embfield2   | listembeddablechilds_order 
-------------------------+--------------+--------------+----------------------------
                       1 | child1field1 | child1field2 |                          0
                       1 | child3field1 | child3field2 |                          1
(2 rows)

Update

log

17:51:19,995 DEBUG [org.hibernate.SQL] (default task-7) select listembedd0_.id as id1_4_0_ from ListEmbeddableParent listembedd0_ where listembedd0_.id=?
17:51:19,996 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [1] as [BIGINT] - [1]
17:51:19,997 DEBUG [org.hibernate.SQL] (default task-7) select listembedd0_.ListEmbeddableParent_id as ListEmbe1_4_0_, listembedd0_.embField1 as embField2_5_0_, listembedd0_.embField2 as embField3_5_0_, listembedd0_.listEmbeddableChilds_ORDER as listEmbe4_0_ from ListEmbeddableParent_listEmbeddableChilds listembedd0_ where listembedd0_.ListEmbeddableParent_id=?
17:51:19,997 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [1] as [BIGINT] - [1]
17:51:20,001 DEBUG [org.hibernate.SQL] (default task-7) update ListEmbeddableParent_listEmbeddableChilds set embField1=?, embField2=? where ListEmbeddableParent_id=? and listEmbeddableChilds_ORDER=?
17:51:20,001 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [1] as [VARCHAR] - [child2field1-updated]
17:51:20,002 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [2] as [VARCHAR] - [child2field2-updated]
17:51:20,002 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [3] as [BIGINT] - [1]
17:51:20,002 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [4] as [INTEGER] - [1]

table

jpatest=# select * from listembeddableparent_listembeddablechilds order by listembeddablechilds_order;
 listembeddableparent_id |      embfield1       |      embfield2       | listembeddablechilds_order 
-------------------------+----------------------+----------------------+----------------------------
                       1 | child1field1         | child1field2         |                          0
                       1 | child2field1-updated | child2field2-updated |                          1
                       1 | child3field1         | child3field2         |                          2
(3 rows)

Remarks

  • It's so convenient for prototypes.
  • Maybe also good for small data sets.

References


Just try to use ElementCollection with Set


Posted on Monday Feb 17, 2014 at 04:25PM in Technology


Just some notes about how it works, how create schemas, and how DMLs executes, and try to find its pros and cons.

Environment

  • WildFly 8.0.0.Final
  • Hibernate 4.3.1
  • PostgreSQL 9.2.4
  • postgresql-9.3-1100.jdbc41.jar

Example project

Whole project resources are available in GitHub.

Set<Basic>

Schema

jpatest=# \d setbasic
   Table "public.setbasic"
 Column |  Type  | Modifiers 
--------+--------+-----------
 id     | bigint | not null
Indexes:
    "setbasic_pkey" PRIMARY KEY, btree (id)
Referenced by:
    TABLE "setbasic_set" CONSTRAINT "fk_qov1oy3cmf1wmttooahy264eh" FOREIGN KEY (setbasic_id) REFERENCES setbasic(id)

jpatest=# \d setbasic_set
           Table "public.setbasic_set"
   Column    |          Type          | Modifiers 
-------------+------------------------+-----------
 setbasic_id | bigint                 | not null
 set         | character varying(255) | 
Foreign-key constraints:
    "fk_qov1oy3cmf1wmttooahy264eh" FOREIGN KEY (setbasic_id) REFERENCES setbasic(id)

jpatest=# 

Entry data

log

13:59:11,377 DEBUG [org.hibernate.SQL] (default task-15) insert into SetBasic (id) values (?)
13:59:11,378 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-15) binding parameter [1] as [BIGINT] - [1]
13:59:11,379 DEBUG [org.hibernate.SQL] (default task-15) insert into SetBasic_set (SetBasic_id, set) values (?, ?)
13:59:11,379 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-15) binding parameter [1] as [BIGINT] - [1]
13:59:11,379 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-15) binding parameter [2] as [VARCHAR] - [hige]
13:59:11,380 DEBUG [org.hibernate.SQL] (default task-15) insert into SetBasic_set (SetBasic_id, set) values (?, ?)
13:59:11,380 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-15) binding parameter [1] as [BIGINT] - [1]
13:59:11,380 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-15) binding parameter [2] as [VARCHAR] - [hoge]
13:59:11,381 DEBUG [org.hibernate.SQL] (default task-15) insert into SetBasic_set (SetBasic_id, set) values (?, ?)
13:59:11,381 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-15) binding parameter [1] as [BIGINT] - [1]
13:59:11,381 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-15) binding parameter [2] as [VARCHAR] - [fuge]

table

jpatest=# select * from setbasic;
 id 
----
  1
(1 row)

jpatest=# select * from setbasic_set;
 setbasic_id | set  
-------------+------
           1 | hige
           1 | hoge
           1 | fuge
(3 rows)

jpatest=# 

Find

14:01:27,838 DEBUG [org.hibernate.SQL] (default task-8) select setbasic0_.id as id1_2_0_ from SetBasic setbasic0_ where setbasic0_.id=?
14:01:27,838 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-8) binding parameter [1] as [BIGINT] - [1]
14:01:27,839 DEBUG [org.hibernate.SQL] (default task-8) select set0_.SetBasic_id as SetBasic1_2_0_, set0_.set as set2_3_0_ from SetBasic_set set0_ where set0_.SetBasic_id=?
14:01:27,840 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-8) binding parameter [1] as [BIGINT] - [1]
14:01:27,839 FINE  [org.nailedtothex.jpatest.set.SetBasicTestDataManipulator] (default task-8) find(): [hige, hoge, fuge]

Add

log

14:03:45,339 DEBUG [org.hibernate.SQL] (default task-15) select setbasic0_.id as id1_2_0_ from SetBasic setbasic0_ where setbasic0_.id=?
14:03:45,340 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-15) binding parameter [1] as [BIGINT] - [1]
14:03:45,341 DEBUG [org.hibernate.SQL] (default task-15) select set0_.SetBasic_id as SetBasic1_2_0_, set0_.set as set2_3_0_ from SetBasic_set set0_ where set0_.SetBasic_id=?
14:03:45,341 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-15) binding parameter [1] as [BIGINT] - [1]
14:03:45,345 DEBUG [org.hibernate.SQL] (default task-15) insert into SetBasic_set (SetBasic_id, set) values (?, ?)
14:03:45,345 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-15) binding parameter [1] as [BIGINT] - [1]
14:03:45,345 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-15) binding parameter [2] as [VARCHAR] - [hege]

table

jpatest=# select * from setbasic_set;
 setbasic_id | set  
-------------+------
           1 | hoge
           1 | hige
           1 | fuge
           1 | hege
(4 rows)

jpatest=# 

Remove

log

14:05:08,367 DEBUG [org.hibernate.SQL] (default task-5) select setbasic0_.id as id1_2_0_ from SetBasic setbasic0_ where setbasic0_.id=?
14:05:08,368 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-5) binding parameter [1] as [BIGINT] - [1]
14:05:08,369 DEBUG [org.hibernate.SQL] (default task-5) select set0_.SetBasic_id as SetBasic1_2_0_, set0_.set as set2_3_0_ from SetBasic_set set0_ where set0_.SetBasic_id=?
14:05:08,369 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-5) binding parameter [1] as [BIGINT] - [1]
14:05:08,374 DEBUG [org.hibernate.SQL] (default task-5) delete from SetBasic_set where SetBasic_id=? and set=?
14:05:08,374 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-5) binding parameter [1] as [BIGINT] - [1]
14:05:08,374 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-5) binding parameter [2] as [VARCHAR] - [hige]

table

jpatest=# select * from setbasic_set;
 setbasic_id | set  
-------------+------
           1 | hoge
           1 | fuge
(2 rows)

jpatest=# 

Set<Embeddable>

Schema

jpatest=# \d setembeddableparent
Table "public.setembeddableparent"
 Column |  Type  | Modifiers 
--------+--------+-----------
 id     | bigint | not null
Indexes:
    "setembeddableparent_pkey" PRIMARY KEY, btree (id)
Referenced by:
    TABLE "setembeddableparent_setembeddablechilds" CONSTRAINT "fk_r8ikgl74hjndujhjwuvnkt59m" FOREIGN KEY (setembeddableparent_id) REFERENCES setembeddableparent(id)

jpatest=# \d setembeddableparent_setembeddablechilds 
   Table "public.setembeddableparent_setembeddablechilds"
         Column         |          Type          | Modifiers 
------------------------+------------------------+-----------
 setembeddableparent_id | bigint                 | not null
 embfield1              | character varying(255) | 
 embfield2              | character varying(255) | 
Foreign-key constraints:
    "fk_r8ikgl74hjndujhjwuvnkt59m" FOREIGN KEY (setembeddableparent_id) REFERENCES setembeddableparent(id)

jpatest=# 

Entry data

log

14:06:58,199 DEBUG [org.hibernate.SQL] (default task-12) insert into SetEmbeddableParent (id) values (?)
14:06:58,199 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-12) binding parameter [1] as [BIGINT] - [1]
14:06:58,200 DEBUG [org.hibernate.SQL] (default task-12) insert into SetEmbeddableParent_setEmbeddableChilds (SetEmbeddableParent_id, embField1, embField2) values (?, ?, ?)
14:06:58,200 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-12) binding parameter [1] as [BIGINT] - [1]
14:06:58,200 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-12) binding parameter [2] as [VARCHAR] - [child3field1]
14:06:58,201 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-12) binding parameter [3] as [VARCHAR] - [child3field2]
14:06:58,201 DEBUG [org.hibernate.SQL] (default task-12) insert into SetEmbeddableParent_setEmbeddableChilds (SetEmbeddableParent_id, embField1, embField2) values (?, ?, ?)
14:06:58,202 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-12) binding parameter [1] as [BIGINT] - [1]
14:06:58,202 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-12) binding parameter [2] as [VARCHAR] - [child2field1]
14:06:58,202 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-12) binding parameter [3] as [VARCHAR] - [child2field2]
14:06:58,202 DEBUG [org.hibernate.SQL] (default task-12) insert into SetEmbeddableParent_setEmbeddableChilds (SetEmbeddableParent_id, embField1, embField2) values (?, ?, ?)
14:06:58,202 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-12) binding parameter [1] as [BIGINT] - [1]
14:06:58,203 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-12) binding parameter [2] as [VARCHAR] - [child1field1]
14:06:58,203 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-12) binding parameter [3] as [VARCHAR] - [child1field2]

table

jpatest=# select * from setembeddableparent;
 id 
----
  1
(1 row)

jpatest=# select * from setembeddableparent_setembeddablechilds;
 setembeddableparent_id |  embfield1   |  embfield2   
------------------------+--------------+--------------
                      1 | child3field1 | child3field2
                      1 | child2field1 | child2field2
                      1 | child1field1 | child1field2
(3 rows)

jpatest=# 

Find

14:10:32,579 DEBUG [org.hibernate.SQL] (default task-6) select setembedda0_.id as id1_4_0_ from SetEmbeddableParent setembedda0_ where setembedda0_.id=?
14:10:32,579 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [1] as [BIGINT] - [1]
14:10:32,580 DEBUG [org.hibernate.SQL] (default task-6) select setembedda0_.SetEmbeddableParent_id as SetEmbed1_4_0_, setembedda0_.embField1 as embField2_5_0_, setembedda0_.embField2 as embField3_5_0_ from SetEmbeddableParent_setEmbeddableChilds setembedda0_ where setembedda0_.SetEmbeddableParent_id=?
14:10:32,581 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [1] as [BIGINT] - [1]
14:10:32,580 FINE  [org.nailedtothex.jpatest.set.SetEmbeddableTestDataManipulator] (default task-6) [SetEmbeddableChild [embField1=child3field1, embField2=child3field2], SetEmbeddableChild [embField1=child2field1, embField2=child2field2], SetEmbeddableChild [embField1=child1field1, embField2=child1field2]]

Add

log

14:12:20,219 DEBUG [org.hibernate.SQL] (default task-13) select setembedda0_.id as id1_4_0_ from SetEmbeddableParent setembedda0_ where setembedda0_.id=?
14:12:20,220 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [1] as [BIGINT] - [1]
14:12:20,221 DEBUG [org.hibernate.SQL] (default task-13) select setembedda0_.SetEmbeddableParent_id as SetEmbed1_4_0_, setembedda0_.embField1 as embField2_5_0_, setembedda0_.embField2 as embField3_5_0_ from SetEmbeddableParent_setEmbeddableChilds setembedda0_ where setembedda0_.SetEmbeddableParent_id=?
14:12:20,221 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [1] as [BIGINT] - [1]
14:12:20,225 DEBUG [org.hibernate.SQL] (default task-13) insert into SetEmbeddableParent_setEmbeddableChilds (SetEmbeddableParent_id, embField1, embField2) values (?, ?, ?)
14:12:20,225 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [1] as [BIGINT] - [1]
14:12:20,225 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [2] as [VARCHAR] - [child4field1]
14:12:20,225 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-13) binding parameter [3] as [VARCHAR] - [child4field2]

table

jpatest=# select * from setembeddableparent_setembeddablechilds;
 setembeddableparent_id |  embfield1   |  embfield2   
------------------------+--------------+--------------
                      1 | child1field1 | child1field2
                      1 | child2field1 | child2field2
                      1 | child3field1 | child3field2
                      1 | child4field1 | child4field2
(4 rows)

Remove

log

14:14:48,499 DEBUG [org.hibernate.SQL] (default task-9) select setembedda0_.id as id1_4_0_ from SetEmbeddableParent setembedda0_ where setembedda0_.id=?
14:14:48,499 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-9) binding parameter [1] as [BIGINT] - [1]
14:14:48,500 DEBUG [org.hibernate.SQL] (default task-9) select setembedda0_.SetEmbeddableParent_id as SetEmbed1_4_0_, setembedda0_.embField1 as embField2_5_0_, setembedda0_.embField2 as embField3_5_0_ from SetEmbeddableParent_setEmbeddableChilds setembedda0_ where setembedda0_.SetEmbeddableParent_id=?
14:14:48,500 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-9) binding parameter [1] as [BIGINT] - [1]
14:14:48,500 FINE  [org.nailedtothex.jpatest.set.SetEmbeddableTestDataManipulator] (default task-9) [SetEmbeddableChild [embField1=child3field1, embField2=child3field2], SetEmbeddableChild [embField1=child2field1, embField2=child2field2], SetEmbeddableChild [embField1=child1field1, embField2=child1field2]]
14:14:48,505 DEBUG [org.hibernate.SQL] (default task-9) delete from SetEmbeddableParent_setEmbeddableChilds where SetEmbeddableParent_id=? and embField1=? and embField2=?
14:14:48,505 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-9) binding parameter [1] as [BIGINT] - [1]
14:14:48,505 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-9) binding parameter [2] as [VARCHAR] - [child1field1]
14:14:48,506 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-9) binding parameter [3] as [VARCHAR] - [child1field2]

table

jpatest=# select * from setembeddableparent_setembeddablechilds;
 setembeddableparent_id |  embfield1   |  embfield2   
------------------------+--------------+--------------
                      1 | child2field1 | child2field2
                      1 | child3field1 | child3field2
(2 rows)

jpatest=# 

Update

log

15:07:27,811 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [1] as [BIGINT] - [1]
15:07:27,812 DEBUG [org.hibernate.SQL] (default task-7) select setembedda0_.SetEmbeddableParent_id as SetEmbed1_2_0_, setembedda0_.embField1 as embField2_3_0_, setembedda0_.embField2 as embField3_3_0_ from SetEmbeddableParent_setEmbeddableChilds setembedda0_ where setembedda0_.SetEmbeddableParent_id=?
15:07:27,812 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [1] as [BIGINT] - [1]
15:07:27,815 DEBUG [org.hibernate.SQL] (default task-7) delete from SetEmbeddableParent_setEmbeddableChilds where SetEmbeddableParent_id=? and embField1=? and embField2=?
15:07:27,815 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [1] as [BIGINT] - [1]
15:07:27,815 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [2] as [VARCHAR] - [child2field1]
15:07:27,815 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [3] as [VARCHAR] - [child2field2]
15:07:27,816 DEBUG [org.hibernate.SQL] (default task-7) insert into SetEmbeddableParent_setEmbeddableChilds (SetEmbeddableParent_id, embField1, embField2) values (?, ?, ?)
15:07:27,816 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [1] as [BIGINT] - [1]
15:07:27,816 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [2] as [VARCHAR] - [child2field1]
15:07:27,816 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-7) binding parameter [3] as [VARCHAR] - [child2field2-updated]

table

jpatest=# select * from setembeddableparent_setembeddablechilds order by embfield1;
 setembeddableparent_id |  embfield1   |      embfield2       
------------------------+--------------+----------------------
                      1 | child1field1 | child1field2
                      1 | child2field1 | child2field2-updated
                      1 | child3field1 | child3field2
(3 rows)

jpatest=# 

Add a duplicate element

14:13:59,763 DEBUG [org.hibernate.SQL] (default task-14) select setembedda0_.id as id1_4_0_ from SetEmbeddableParent setembedda0_ where setembedda0_.id=?
14:13:59,764 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [1] as [BIGINT] - [1]
14:13:59,765 DEBUG [org.hibernate.SQL] (default task-14) select setembedda0_.SetEmbeddableParent_id as SetEmbed1_4_0_, setembedda0_.embField1 as embField2_5_0_, setembedda0_.embField2 as embField3_5_0_ from SetEmbeddableParent_setEmbeddableChilds setembedda0_ where setembedda0_.SetEmbeddableParent_id=?
14:13:59,765 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-14) binding parameter [1] as [BIGINT] - [1]
  • No changes are made to DB.

Remove a element that not exist

14:16:48,827 DEBUG [org.hibernate.SQL] (default task-10) select setembedda0_.id as id1_4_0_ from SetEmbeddableParent setembedda0_ where setembedda0_.id=?
14:16:48,828 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-10) binding parameter [1] as [BIGINT] - [1]
14:16:48,829 DEBUG [org.hibernate.SQL] (default task-10) select setembedda0_.SetEmbeddableParent_id as SetEmbed1_4_0_, setembedda0_.embField1 as embField2_5_0_, setembedda0_.embField2 as embField3_5_0_ from SetEmbeddableParent_setEmbeddableChilds setembedda0_ where setembedda0_.SetEmbeddableParent_id=?
14:16:48,829 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-10) binding parameter [1] as [BIGINT] - [1]
  • No changes are made to DB.

Nested collection is prohibited

  • It said @ElementCollection can be used with embeddable or basic type only.

Conclusion

Pros

  • It works well as expected for some operations of Set API. it prevents that add duplicated elements.
  • It can reduce some annoying codes.

Cons

  • All elements are need to being fetched for manipulate, so maybe it is not good for large sets.
  • Child elements are not entities, so use of some convenient operations is impossible.

Remarks

  • Maybe it's good for proto-typing.
  • But I'm not sure about whether it is appropriate for production systems especially high-traffic concurrent systems.
  • For appropriate size sets, maybe 2nd level cache would be great help for its performance.