Just try to use ElementCollection with List
TweetPosted 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
Tags: jpa
Just try to use ElementCollection with Set
TweetPosted 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.
Tags: jpa
ExitStatusでフロー制御してみる
TweetPosted on Sunday Feb 16, 2014 at 08:17AM in Technology
ExitStatusでフロー制御的なことをして遊んでみる
環境・前提条件
- Chunk方式のStepで例外発生時にスキップさせてみると同じ。ここで作ったプロジェクトが普通に動いているものとする
仕様を見てみる
[1]から引いてみる
8.6 Transition Elements
Transition elements may be specified in the containment scope of a step, flow, split, or decision to direct job execution sequence or to terminate job execution. There are four transition elements:
- next - directs execution flow to the next execution element.
- fail - causes a job to end with FAILED batch status.
- end - causes a job to end with COMPLETED batch status.
- stop - causes a job to end with STOPPED batch status.
Fail end, and stop are considered “terminating elements” because they cause a job execution to terminate.
この4つを使って遊んでみる
サンプルの仕様
- 第一レベルの要素は以下
- step1
- step2
- どちらも参照するartifactは同じExitStatusBatchlet
- パラメータで与えたExitStatusで終わるだけ
- step1のExitStatusはジョブパラメータで変えられるようにしてある
- step2のExitStatusはnull(COMPLETED)固定
- step1には先で引いたTransition Elementsを4つ指定してある
- 4つのテストメソッドでstep1のExitStatusを以下のパターンで変えてテストする
- next(): step2に遷移する
- fail(): step1で異常終了
- end(): step1で正常終了
- stop(): step1で停止
資源
資源はこのへんにまとめて全部ある
動かしてみる
next
ログ
10:29:46,990 FINE [org.nailedtothex.jbatch.example.on.ExitStatusBatchlet] (batch-batch - 6) step1: exitStatus=NEXT 10:29:47,009 FINE [org.nailedtothex.jbatch.example.on.ExitStatusBatchlet] (batch-batch - 6) step2: exitStatus=null
Repository
job_execution
jbatch=# select * from job_execution order by jobexecutionid desc limit 1; jobexecutionid | jobinstanceid | version | createtime | starttime | endtime | lastupdatedtime | batchstatus | exitstatus | jobparameters | restartposition ----------------+---------------+---------+-------------------------+-------------------------+-------------------------+-------------------------+-------------+------------+-------------------+----------------- 148 | 141 | | 2014-02-16 10:29:46.976 | 2014-02-16 10:29:46.976 | 2014-02-16 10:29:47.011 | 2014-02-16 10:29:47.011 | COMPLETED | COMPLETED | exitStatus = NEXT+| | | | | | | | | | | (1 row)
step_execution
jbatch=# select * from step_execution where jobexecutionid in (148) order by jobexecutionid, stepexecutionid; stepexecutionid | jobexecutionid | version | stepname | starttime | endtime | batchstatus | exitstatus | executionexception | persistentuserdata | readcount | writecount | commitcount | rollbackcount | readskipcount | processskipcount | filtercount | writeskipcount | readercheckpointinfo | writercheckpointinfo -----------------+----------------+---------+----------+-------------------------+-------------------------+-------------+------------+--------------------+--------------------+-----------+------------+-------------+---------------+---------------+------------------+-------------+----------------+----------------------+---------------------- 171 | 148 | | step1 | 2014-02-16 10:29:46.982 | 2014-02-16 10:29:46.991 | COMPLETED | NEXT | | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 172 | 148 | | step2 | 2014-02-16 10:29:47.008 | 2014-02-16 10:29:47.009 | COMPLETED | COMPLETED | | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | (2 rows)
- 普通にstep2に遷移している
fail
ログ
10:41:31,341 FINE [org.nailedtothex.jbatch.example.on.ExitStatusBatchlet] (batch-batch - 9) step1: exitStatus=FAIL
Repository
job_execution
jbatch=# select * from job_execution order by jobexecutionid desc limit 1; jobexecutionid | jobinstanceid | version | createtime | starttime | endtime | lastupdatedtime | batchstatus | exitstatus | jobparameters | restartposition ----------------+---------------+---------+-------------------------+-------------------------+-------------------------+-------------------------+-------------+---------------------------+-------------------+----------------- 149 | 142 | | 2014-02-16 10:41:31.338 | 2014-02-16 10:41:31.338 | 2014-02-16 10:41:31.344 | 2014-02-16 10:41:31.344 | FAILED | EARLY COMPLETION (FAILED) | exitStatus = FAIL+| | | | | | | | | | | (1 row)
step_execution
jbatch=# select * from step_execution where jobexecutionid in (149) order by jobexecutionid, stepexecutionid; stepexecutionid | jobexecutionid | version | stepname | starttime | endtime | batchstatus | exitstatus | executionexception | persistentuserdata | readcount | writecount | commitcount | rollbackcount | readskipcount | processskipcount | filtercount | writeskipcount | readercheckpointinfo | writercheckpointinfo -----------------+----------------+---------+----------+-------------------------+-------------------------+-------------+------------+--------------------+--------------------+-----------+------------+-------------+---------------+---------------+------------------+-------------+----------------+----------------------+---------------------- 173 | 149 | | step1 | 2014-02-16 10:41:31.339 | 2014-02-16 10:41:31.341 | COMPLETED | FAIL | | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | (1 row)
- step1終了後に異常終了している
- step_executionのbatchstatusがCOMPLETEDなのが気になるけどjob_executionのbatchstatusはちゃんとFAILEDになっている
end
ログ
10:43:54,134 FINE [org.nailedtothex.jbatch.example.on.ExitStatusBatchlet] (batch-batch - 3) step1: exitStatus=END
Repository
job_execution
jbatch=# select * from job_execution order by jobexecutionid desc limit 1; jobexecutionid | jobinstanceid | version | createtime | starttime | endtime | lastupdatedtime | batchstatus | exitstatus | jobparameters | restartposition ----------------+---------------+---------+-------------------------+-------------------------+-------------------------+-------------------------+-------------+------------------------+------------------+----------------- 150 | 143 | | 2014-02-16 10:43:54.129 | 2014-02-16 10:43:54.129 | 2014-02-16 10:43:54.137 | 2014-02-16 10:43:54.137 | COMPLETED | EARLY COMPLETION (END) | exitStatus = END+| | | | | | | | | | | (1 row)
step_execution
jbatch=# select * from step_execution where jobexecutionid in (150) order by jobexecutionid, stepexecutionid; stepexecutionid | jobexecutionid | version | stepname | starttime | endtime | batchstatus | exitstatus | executionexception | persistentuserdata | readcount | writecount | commitcount | rollbackcount | readskipcount | processskipcount | filtercount | writeskipcount | readercheckpointinfo | writercheckpointinfo -----------------+----------------+---------+----------+------------------------+-------------------------+-------------+------------+--------------------+--------------------+-----------+------------+-------------+---------------+---------------+------------------+-------------+----------------+----------------------+---------------------- 174 | 150 | | step1 | 2014-02-16 10:43:54.13 | 2014-02-16 10:43:54.134 | COMPLETED | END | | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | (1 row)
- step2には遷移せず正常終了している
stop
ログ
10:46:52,718 FINE [org.nailedtothex.jbatch.example.on.ExitStatusBatchlet] (batch-batch - 2) step1: exitStatus=STOP
Repository
job_execution
jbatch=# select * from job_execution order by jobexecutionid desc limit 1; jobexecutionid | jobinstanceid | version | createtime | starttime | endtime | lastupdatedtime | batchstatus | exitstatus | jobparameters | restartposition ----------------+---------------+---------+-------------------------+-------------------------+------------------------+------------------------+-------------+-------------------------+-------------------+----------------- 151 | 144 | | 2014-02-16 10:46:52.705 | 2014-02-16 10:46:52.705 | 2014-02-16 10:46:52.72 | 2014-02-16 10:46:52.72 | STOPPED | EARLY COMPLETION (STOP) | exitStatus = STOP+| step2 | | | | | | | | | | (1 row)
step_execution
jbatch=# select * from step_execution where jobexecutionid in (151) order by jobexecutionid, stepexecutionid; stepexecutionid | jobexecutionid | version | stepname | starttime | endtime | batchstatus | exitstatus | executionexception | persistentuserdata | readcount | writecount | commitcount | rollbackcount | readskipcount | processskipcount | filtercount | writeskipcount | readercheckpointinfo | writercheckpointinfo -----------------+----------------+---------+----------+-------------------------+-------------------------+-------------+------------+--------------------+--------------------+-----------+------------+-------------+---------------+---------------+------------------+-------------+----------------+----------------------+---------------------- 175 | 151 | | step1 | 2014-02-16 10:46:52.712 | 2014-02-16 10:46:52.718 | COMPLETED | STOP | | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | (1 row)
- step1終了後に停止している
- step_executionのbatchstatusがCOMPLETEDなのが気になるけどjob_executionのbatchstatusはちゃんとSTOPPEDになっている
stop要素のrestart属性で再実行時に遷移するstepを指定してみる
仕様を引いてみる
[1]の「8.6.4 Stop Element」に、restart属性についてこう書いてある
Specifies the job-level step, flow, or split at which to restart when the job is restarted. It must be a valid XML string value. This is a required attribute.
再実行してみる
テストメソッドstopRestart()に再実行のテストを書いてあるので実行してみる
ログ
10:58:59,039 FINE [org.nailedtothex.jbatch.example.on.ExitStatusBatchlet] (batch-batch - 4) step1: exitStatus=STOP 10:59:00,053 WARN [org.jberet] (batch-batch - 6) JBERET000018: Could not find the original step execution to restart. Current step execution id: 0, step name: step2 10:59:00,054 FINE [org.nailedtothex.jbatch.example.on.ExitStatusBatchlet] (batch-batch - 6) step2: exitStatus=null
Repository
job_execution
jbatch=# select * from job_execution where jobexecutionid in (161, 162) order by jobexecutionid; jobexecutionid | jobinstanceid | version | createtime | starttime | endtime | lastupdatedtime | batchstatus | exitstatus | jobparameters | restartposition ----------------+---------------+---------+-------------------------+-------------------------+-------------------------+-------------------------+-------------+-------------------------+-------------------+----------------- 161 | 151 | | 2014-02-16 10:58:59.035 | 2014-02-16 10:58:59.035 | 2014-02-16 10:58:59.042 | 2014-02-16 10:58:59.042 | STOPPED | EARLY COMPLETION (STOP) | exitStatus = STOP+| step2 | | | | | | | | | | 162 | 151 | | 2014-02-16 10:59:00.05 | 2014-02-16 10:59:00.05 | 2014-02-16 10:59:00.056 | 2014-02-16 10:59:00.056 | COMPLETED | COMPLETED | exitStatus = STOP+| | | | | | | | | | | (2 rows)
step_execution
jbatch=# select * from step_execution where jobexecutionid in (161, 162) order by jobexecutionid, stepexecutionid; stepexecutionid | jobexecutionid | version | stepname | starttime | endtime | batchstatus | exitstatus | executionexception | persistentuserdata | readcount | writecount | commitcount | rollbackcount | readskipcount | processskipcount | filtercount | writeskipcount | readercheckpointinfo | writercheckpointinfo -----------------+----------------+---------+----------+-------------------------+-------------------------+-------------+------------+--------------------+--------------------+-----------+------------+-------------+---------------+---------------+------------------+-------------+----------------+----------------------+---------------------- 186 | 161 | | step1 | 2014-02-16 10:58:59.037 | 2014-02-16 10:58:59.04 | COMPLETED | STOP | | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 187 | 162 | | step2 | 2014-02-16 10:59:00.051 | 2014-02-16 10:59:00.054 | COMPLETED | COMPLETED | | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | (2 rows)
- 一応予想通り動いたけど、ログにWARNで出ている文言が気になる
- 再実行時に初回実行時に実行してないStepから再開するっていうのは仕様上微妙なのかも
備考
- on属性にはワイルドカード(*と?)が使える
- next on=“*” とかよく使いそう
- endは正常系で後続処理やらなくて良い時に使う感じ。非営業日だから何もせずに終わりとか(営業日関連はジョブ内でやらずに、ジョブ呼び出すところを作り込んでジョブが動く前に止めた方がいい気がするけど)
- failは異常系の時(例外投げてもいい気がするけど)
- stopは再実行前提で止めたい時とか、再実行するstepを制御したい時に使う?どういう状況で使うのかいまいち想像できないけど
- 先行処理の状況から分岐させたいときは、StepExecutionの配列を受け取ってExitStatusを決められるDeciderを使うのが良い
参考文献
Tags: jbatch
A way to resolve dependencies of jobs
TweetPosted on Sunday Feb 16, 2014 at 08:17AM in Technology
This is about a way to resolve dependencies of jobs that used only JSR 352 API.
Environment
- jBeret 1.0.1Beta-SNAPSHOT
- WildFly 8.0.0.Final
Why need it?
- For tasks that need to execute sequentially, usually we have to let all tasks in single job XML.
- I guess it would bring huge difficulty of testing.
- For example, I don't want to test such big job like EndOfTheDay.xml
- Rather than I would go with smaller jobs with external job control system.
How realize it?
- This needs to create parent job XML that defines dependencies of child jobs.
- Every step uses artifact named “jobLauncherBatchlet”
- This batchlet invokes child job. name of the job and job parameters are given by its parameter of the step.
- After invoke the job, then it starts polling BatchStatus, and wait till the job is finished.
Sample project
Whole resources are available in GitHub.
- Artifacts
- jobXMLs
- Test class
log
13:45:22,589 FINE [org.nailedtothex.jbatch.example.jobdependency.JobLaunchBatchlet] (batch-batch - 8) step1: persistentUserData=null, waitForFinish=null 13:45:22,589 FINE [org.nailedtothex.jbatch.example.jobdependency.JobLaunchBatchlet] (batch-batch - 8) step1: starting new job: jobXMLName=jobdependency-child1, properties={sleepInMillis=1000} 13:45:22,593 FINE [org.nailedtothex.jbatch.example.jobdependency.JobLaunchBatchlet] (batch-batch - 8) step1: job started: executionId=207 13:45:22,593 FINE [org.nailedtothex.jbatch.example.jobdependency.JobLaunchBatchlet] (batch-batch - 8) step1: waiting for finish the job... executionId=207 13:45:22,595 FINE [org.nailedtothex.jbatch.example.split.SleepBatchlet] (batch-batch - 2) entering process(): stepName=child1-step1, sleepInMills=1,000 13:45:23,596 FINE [org.nailedtothex.jbatch.example.split.SleepBatchlet] (batch-batch - 2) exiting process(): stepName=child1-step1, sleepInMills=1,000 13:45:24,595 FINE [org.nailedtothex.jbatch.example.jobdependency.JobLaunchBatchlet] (batch-batch - 8) step1: job finished: BatchStatus=COMPLETED 13:45:24,601 FINE [org.nailedtothex.jbatch.example.jobdependency.JobLaunchBatchlet] (batch-batch - 8) step2: persistentUserData=null, waitForFinish=null 13:45:24,601 FINE [org.nailedtothex.jbatch.example.jobdependency.JobLaunchBatchlet] (batch-batch - 8) step2: starting new job: jobXMLName=jobdependency-child2, properties={sleepInMillis=2000} 13:45:24,605 FINE [org.nailedtothex.jbatch.example.jobdependency.JobLaunchBatchlet] (batch-batch - 8) step2: job started: executionId=208 13:45:24,605 FINE [org.nailedtothex.jbatch.example.jobdependency.JobLaunchBatchlet] (batch-batch - 8) step2: waiting for finish the job... executionId=208 13:45:24,606 FINE [org.nailedtothex.jbatch.example.split.SleepBatchlet] (batch-batch - 4) entering process(): stepName=child2-step1, sleepInMills=2,000 13:45:26,608 FINE [org.nailedtothex.jbatch.example.split.SleepBatchlet] (batch-batch - 4) exiting process(): stepName=child2-step1, sleepInMills=2,000 13:45:27,608 FINE [org.nailedtothex.jbatch.example.jobdependency.JobLaunchBatchlet] (batch-batch - 8) step2: job finished: BatchStatus=COMPLETED 13:45:27,614 FINE [org.nailedtothex.jbatch.example.jobdependency.JobLaunchBatchlet] (batch-batch - 8) step3: persistentUserData=null, waitForFinish=null 13:45:27,614 FINE [org.nailedtothex.jbatch.example.jobdependency.JobLaunchBatchlet] (batch-batch - 8) step3: starting new job: jobXMLName=jobdependency-child3, properties={sleepInMillis=3000} 13:45:27,618 FINE [org.nailedtothex.jbatch.example.jobdependency.JobLaunchBatchlet] (batch-batch - 8) step3: job started: executionId=209 13:45:27,618 FINE [org.nailedtothex.jbatch.example.jobdependency.JobLaunchBatchlet] (batch-batch - 8) step3: waiting for finish the job... executionId=209 13:45:27,619 FINE [org.nailedtothex.jbatch.example.split.SleepBatchlet] (batch-batch - 9) entering process(): stepName=child3-step1, sleepInMills=3,000 13:45:30,620 FINE [org.nailedtothex.jbatch.example.split.SleepBatchlet] (batch-batch - 9) exiting process(): stepName=child3-step1, sleepInMills=3,000 13:45:31,620 FINE [org.nailedtothex.jbatch.example.jobdependency.JobLaunchBatchlet] (batch-batch - 8) step3: job finished: BatchStatus=COMPLETED
Job repository tables
job_instance and job_execution
jbatch=# select * from job_instance i, job_execution e where i.jobinstanceid = e.jobinstanceid and i.jobname like 'jobdependency%' and i.jobinstanceid >= 194 order by e.jobexecutionid; jobinstanceid | version | jobname | applicationname | jobexecutionid | jobinstanceid | version | createtime | starttime | endtime | lastupdatedtime | batchstatus | exitstatus | jobparameters | restartposition ---------------+---------+----------------------+-----------------+----------------+---------------+---------+-------------------------+-------------------------+-------------------------+-------------------------+-------------+------------+----------------------+----------------- 194 | | jobdependency | jbatchtest | 206 | 194 | | 2014-02-19 13:45:22.586 | 2014-02-19 13:45:22.586 | 2014-02-19 13:45:31.623 | 2014-02-19 13:45:31.623 | COMPLETED | COMPLETED | | 195 | | jobdependency-child1 | jbatchtest | 207 | 195 | | 2014-02-19 13:45:22.592 | 2014-02-19 13:45:22.592 | 2014-02-19 13:45:23.599 | 2014-02-19 13:45:23.599 | COMPLETED | COMPLETED | sleepInMillis = 1000+| | | | | | | | | | | | | | | 196 | | jobdependency-child2 | jbatchtest | 208 | 196 | | 2014-02-19 13:45:24.604 | 2014-02-19 13:45:24.604 | 2014-02-19 13:45:26.611 | 2014-02-19 13:45:26.611 | COMPLETED | COMPLETED | sleepInMillis = 2000+| | | | | | | | | | | | | | | 197 | | jobdependency-child3 | jbatchtest | 209 | 197 | | 2014-02-19 13:45:27.617 | 2014-02-19 13:45:27.617 | 2014-02-19 13:45:30.624 | 2014-02-19 13:45:30.624 | COMPLETED | COMPLETED | sleepInMillis = 3000+| | | | | | | | | | | | | | | (4 rows)
step_execution
jbatch=# select * from step_execution s, job_execution e, job_instance i where s.jobexecutionid = e.jobexecutionid and e.jobinstanceid = i.jobinstanceid and i.jobinstanceid >= 194 order by s.starttime; stepexecutionid | jobexecutionid | version | stepname | starttime | endtime | batchstatus | exitstatus | executionexception | persistentuserdata | readcount | writecount | commitcount | rollbackcount | readskipcount | processskipcount | filtercount | writeskipcount | readercheckpointinfo | writercheckpointinfo | jobexecutionid | jobinstanceid | version | createtime | starttime | endtime | lastupdatedtime | batchstatus | exitstatus | jobparameters | restartposition | jobinstanceid | version | jobname | applicationname -----------------+----------------+---------+--------------+-------------------------+-------------------------+-------------+------------+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+------------+-------------+---------------+---------------+------------------+-------------+----------------+----------------------+----------------------+----------------+---------------+---------+-------------------------+-------------------------+-------------------------+-------------------------+-------------+------------+----------------------+-----------------+---------------+---------+----------------------+----------------- 277 | 206 | | step1 | 2014-02-19 13:45:22.587 | 2014-02-19 13:45:24.595 | COMPLETED | COMPLETED | | \xaced00057372000e6a6176612e6c616e672e4c6f6e673b8be490cc8f23df0200014a000576616c7565787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b020000787000000000000000cf | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | | 206 | 194 | | 2014-02-19 13:45:22.586 | 2014-02-19 13:45:22.586 | 2014-02-19 13:45:31.623 | 2014-02-19 13:45:31.623 | COMPLETED | COMPLETED | | | 194 | | jobdependency | jbatchtest 278 | 207 | | child1-step1 | 2014-02-19 13:45:22.593 | 2014-02-19 13:45:23.596 | COMPLETED | SUCCESS | | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | | 207 | 195 | | 2014-02-19 13:45:22.592 | 2014-02-19 13:45:22.592 | 2014-02-19 13:45:23.599 | 2014-02-19 13:45:23.599 | COMPLETED | COMPLETED | sleepInMillis = 1000+| | 195 | | jobdependency-child1 | jbatchtest | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 279 | 206 | | step2 | 2014-02-19 13:45:24.599 | 2014-02-19 13:45:27.608 | COMPLETED | COMPLETED | | \xaced00057372000e6a6176612e6c616e672e4c6f6e673b8be490cc8f23df0200014a000576616c7565787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b020000787000000000000000d0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | | 206 | 194 | | 2014-02-19 13:45:22.586 | 2014-02-19 13:45:22.586 | 2014-02-19 13:45:31.623 | 2014-02-19 13:45:31.623 | COMPLETED | COMPLETED | | | 194 | | jobdependency | jbatchtest 280 | 208 | | child2-step1 | 2014-02-19 13:45:24.605 | 2014-02-19 13:45:26.608 | COMPLETED | SUCCESS | | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | | 208 | 196 | | 2014-02-19 13:45:24.604 | 2014-02-19 13:45:24.604 | 2014-02-19 13:45:26.611 | 2014-02-19 13:45:26.611 | COMPLETED | COMPLETED | sleepInMillis = 2000+| | 196 | | jobdependency-child2 | jbatchtest | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 281 | 206 | | step3 | 2014-02-19 13:45:27.612 | 2014-02-19 13:45:31.621 | COMPLETED | COMPLETED | | \xaced00057372000e6a6176612e6c616e672e4c6f6e673b8be490cc8f23df0200014a000576616c7565787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b020000787000000000000000d1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | | 206 | 194 | | 2014-02-19 13:45:22.586 | 2014-02-19 13:45:22.586 | 2014-02-19 13:45:31.623 | 2014-02-19 13:45:31.623 | COMPLETED | COMPLETED | | | 194 | | jobdependency | jbatchtest 282 | 209 | | child3-step1 | 2014-02-19 13:45:27.618 | 2014-02-19 13:45:30.62 | COMPLETED | SUCCESS | | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | | 209 | 197 | | 2014-02-19 13:45:27.617 | 2014-02-19 13:45:27.617 | 2014-02-19 13:45:30.624 | 2014-02-19 13:45:30.624 | COMPLETED | COMPLETED | sleepInMillis = 3000+| | 197 | | jobdependency-child3 | jbatchtest | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | (6 rows)
- We can see that they were executed in particular order.
Remarks
- I intent to care of stop and restart, and sample project contains some codes about it, but I haven't tested it yet. maybe I would write about it too later.
- It can use some functions of jobXML such as parallel executions (like split element) for control of job execution even.
Take care of the max number of threads in thread-pool
- Some implementations have limit of threads count.
- When you used this method or similar one with many parallel execution elements (split or partition), you must ensure to keep number of threads lower than the limit.
- If limit reaches, your batch will be frozen and it won't resume.
How to configure max threads
- On WildFly + jBeret, the max number of threads is set to 10 as default.
- This increases the limit to 100:
/subsystem=batch/thread-pool=batch:write-attribute(name=max-threads, value=100)
Tags: jbatch
StepContext#persistentUserDataで遊ぶ
TweetPosted on Sunday Feb 16, 2014 at 07:43AM in Technology
StepContext#persistentUserDataにはStepに紐づくデータを保存しておける。ここに入れたデータはJobRepositoryに保存され、後続のStepやジョブの再実行時に参照できる。何かしら使い道があると思われるので若干遊んでみる
環境・前提条件
- Chunk方式のStepで例外発生時にスキップさせてみると同じ。ここで作ったプロジェクトが普通に動いているものとする
関連メソッドの仕様を見てみる
[1]から引いてみる
javax.batch.runtime.context.StepContextインタフェース
Stepに関連する操作をする時に使うインタフェース。artifactで@Injectで注入して使える。
/** * The getPersistentUserData method returns a persistent data object * belonging to the current step. The user data type must implement * java.util.Serializable. This data is saved as part of a step's * checkpoint. For a step that does not do checkpoints, it is saved * after the step ends. It is available upon restart. * @return user-specified type */ public Serializable getPersistentUserData(); /** * The setPersistentUserData method stores a persistent data object * into the current step. The user data type must implement * java.util.Serializable. This data is saved as part of a step's * checkpoint. For a step that does not do checkpoints, it is saved * after the step ends. It is available upon restart. * @param data is the user-specified type */ public void setPersistentUserData(Serializable data);
javax.batch.runtime.StepExecutionインタフェース
Stepの実行履歴的な情報を含むインタフェース。JobOperatorを使って引っ張って来れたり、Deciderのメソッドの引数で受け取れたりする。
/** * Get user persistent data * @return persistent data */ public Serializable getPersistentUserData();
先行StepでセットしたpersistentUserDataを後続Stepで参照してみる
サンプルの仕様
- 第一レベルの要素は動作順に以下
- set (setPersistentUserDataBatchlet)
- get (getPersistentUserDataBatchlet)
- setでセットしたpersistentUserDataをgetで参照してみる
資源
資源はこのへんにまとめて全部ある
- バッチ本体
- テスト
動かしてみる
ログ
08:52:02,642 FINE [org.nailedtothex.jbatch.example.persistentuserdata.SetPersistentUserDataBatchlet] (batch-batch - 4) set: process() 08:52:02,649 FINE [org.nailedtothex.jbatch.example.persistentuserdata.GetPersistentUserDataBatchlet] (batch-batch - 4) get: process() 08:52:02,650 FINE [org.nailedtothex.jbatch.example.persistentuserdata.GetPersistentUserDataBatchlet] (batch-batch - 4) stepExecution: stepName=set, persistentUserData=* my step name is set * 08:52:02,650 FINE [org.nailedtothex.jbatch.example.persistentuserdata.GetPersistentUserDataBatchlet] (batch-batch - 4) stepExecution: stepName=get, persistentUserData=null
setステップで設定した「 my step name is set 」がgetステップから見えている(3行目)。うむ
Repository
job_execution
jbatch=# select * from job_execution order by jobexecutionid desc limit 1; jobexecutionid | jobinstanceid | version | createtime | starttime | endtime | lastupdatedtime | batchstatus | exitstatus | jobparameters | restartposition ----------------+---------------+---------+-------------------------+-------------------------+-------------------------+-------------------------+-------------+------------+---------------+----------------- 131 | 126 | | 2014-02-16 08:52:02.637 | 2014-02-16 08:52:02.637 | 2014-02-16 08:52:02.653 | 2014-02-16 08:52:02.653 | COMPLETED | COMPLETED | | (1 row)
step_execution
jbatch=# select * from step_execution where jobexecutionid = 131 order by stepexecutionid; stepexecutionid | jobexecutionid | version | stepname | starttime | endtime | batchstatus | exitstatus | executionexception | persistentuserdata | readcount | writecount | commitcount | rollbackcount | readskipcount | processskipcount | filtercount | writeskipcount | readercheckpointinfo | writercheckpointinfo -----------------+----------------+---------+----------+-------------------------+-------------------------+-------------+------------+--------------------+----------------------------------------------------------------+-----------+------------+-------------+---------------+---------------+------------------+-------------+----------------+----------------------+---------------------- 153 | 131 | | set | 2014-02-16 08:52:02.639 | 2014-02-16 08:52:02.642 | COMPLETED | COMPLETED | | \xaced00057400172a206d792073746570206e616d6520697320736574202a | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 154 | 131 | | get | 2014-02-16 08:52:02.645 | 2014-02-16 08:52:02.65 | COMPLETED | COMPLETED | | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | (2 rows)
persistentuserdataカラムに何かが入っている。うむ
前回実行時のデータを再実行時に参照してみる
サンプルの仕様
- Stepは1つだけ
- 何もpersistentUserDataに入ってなかったら
- persistentUserDataにデータを入れる
- 例外投げて死ぬ
- 何かpersistentUserDataに入っていたら
- 内容を表示して終了
- 初回実行はpersistentUserDataにデータ入れてFAILEDになる
- 再実行時はpersistentUserDataのデータを表示してCOMPLETEDになる
資源
資源はこのへんにまとめて全部ある
- バッチ本体
- テスト
動かしてみる
ログ
09:15:07,338 FINE [org.nailedtothex.jbatch.example.persistentuserdata.GetAndSetPersistentUserDataBatchlet] (batch-batch - 3) getAndSet: process() 09:15:07,339 WARN [org.jberet] (batch-batch - 3) JBERET000001: Failed to run batchlet org.jberet.job.model.RefArtifact@7e76d151: java.lang.RuntimeException: to confirm whether the data is visible or not when restart at org.nailedtothex.jbatch.example.persistentuserdata.GetAndSetPersistentUserDataBatchlet.process(GetAndSetPersistentUserDataBatchlet.java:31) [classes:] at org.jberet.runtime.runner.BatchletRunner.run(BatchletRunner.java:61) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT] at org.jberet.runtime.runner.StepExecutionRunner.runBatchletOrChunk(StepExecutionRunner.java:207) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT] at org.jberet.runtime.runner.StepExecutionRunner.run(StepExecutionRunner.java:131) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT] at org.jberet.runtime.runner.CompositeExecutionRunner.runStep(CompositeExecutionRunner.java:162) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT] at org.jberet.runtime.runner.CompositeExecutionRunner.runFromHeadOrRestartPoint(CompositeExecutionRunner.java:88) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT] at org.jberet.runtime.runner.JobExecutionRunner.run(JobExecutionRunner.java:58) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT] at org.wildfly.jberet.services.BatchEnvironmentService$WildFlyBatchEnvironment$1.run(BatchEnvironmentService.java:149) [wildfly-jberet-8.0.0.Final.jar:8.0.0.Final] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [rt.jar:1.7.0_51] at java.util.concurrent.FutureTask.run(FutureTask.java:262) [rt.jar:1.7.0_51] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_51] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_51] at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_51] at org.jboss.threads.JBossThread.run(JBossThread.java:122) 09:15:08,351 FINE [org.nailedtothex.jbatch.example.persistentuserdata.GetAndSetPersistentUserDataBatchlet] (batch-batch - 2) getAndSet: process() 09:15:08,351 FINE [org.nailedtothex.jbatch.example.persistentuserdata.GetAndSetPersistentUserDataBatchlet] (batch-batch - 2) persistentUserData=* my job execution id is 134 *
初回実行時に入れた「 my job execution id is 134 」が再実行時に見えている。うむ
Repository
job_execution
jbatch=# select * from job_execution where jobexecutionid in (134, 135) order by jobexecutionid; jobexecutionid | jobinstanceid | version | createtime | starttime | endtime | lastupdatedtime | batchstatus | exitstatus | jobparameters | restartposition ----------------+---------------+---------+-------------------------+-------------------------+-------------------------+-------------------------+-------------+------------+---------------+----------------- 134 | 128 | | 2014-02-16 09:15:07.335 | 2014-02-16 09:15:07.335 | 2014-02-16 09:15:07.343 | 2014-02-16 09:15:07.343 | FAILED | FAILED | | 135 | 128 | | 2014-02-16 09:15:08.347 | 2014-02-16 09:15:08.347 | 2014-02-16 09:15:08.354 | 2014-02-16 09:15:08.354 | COMPLETED | COMPLETED | | (2 rows)
step_execution
jbatch=# select * from step_execution where jobexecutionid in (134, 135) order by jobexecutionid, stepexecutionid; stepexecutionid | jobexecutionid | version | stepname | starttime | endtime | batchstatus | exitstatus | executionexception | persistentuserdata | readcount | writecount | commitcount | rollbackcount | readskipcount | processskipcount | filtercount | writeskipcount | readercheckpointinfo | writercheckpointinfo -----------------+----------------+---------+-----------+-------------------------+-------------------------+-------------+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------+-----------+------------+-------------+---------------+---------------+------------------+-------------+----------------+----------------------+---------------------- 157 | 134 | | getAndSet | 2014-02-16 09:15:07.336 | 2014-02-16 09:15:07.34 | FAILED | FAILED | java.lang.RuntimeException: to confirm whether the data is visible or not when restart +| \xaced000574001e2a206d79206a6f6220657865637574696f6e20696420697320313334202a | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | | | | | | | | | at org.nailedtothex.jbatch.example.persistentuserdata.GetAndSetPersistentUserDataBatchlet.process(GetAndSetPersistentUserDataBatchlet.java:31)+| | | | | | | | | | | | | | | | | | | at org.jberet.runtime.runner.BatchletRunner.run(BatchletRunner.java:61) +| | | | | | | | | | | | | | | | | | | at org.jberet.runtime.runner.StepExecutionRunner.runBatchletOrChunk(StepExecutionRunner.java:207) +| | | | | | | | | | | | | | | | | | | at org.jberet.runtime.runner.StepExecutionRunner.run(StepExecutionRunner.java:131) +| | | | | | | | | | | | | | | | | | | at org.jberet.runtime.runner.CompositeExecutionRunner.runStep(CompositeExecutionRunner.java:162) +| | | | | | | | | | | | | | | | | | | at org.jberet.runtime.runner.CompositeExecutionRunner.runFromHeadOrRestartPoint(CompositeExecutionRunner.java:88) +| | | | | | | | | | | | | | | | | | | at org.jberet.runtime.runner.JobExecutionRunner.run(JobExecutionRunner.java:58) +| | | | | | | | | | | | | | | | | | | at org.wildfly.jberet.services.BatchEnvironmentService$WildFlyBatchEnvironment$1.run(BatchEnvironmentService.java:149) +| | | | | | | | | | | | | | | | | | | at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) +| | | | | | | | | | | | | | | | | | | at java.util.concurrent.FutureTask.run(FutureTask.java:262) +| | | | | | | | | | | | | | | | | | | at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +| | | | | | | | | | | | | | | | | | | at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) +| | | | | | | | | | | | | | | | | | | at java.lang.Thread.run(Thread.java:744) +| | | | | | | | | | | | | | | | | | | at org.jboss.threads.JBossThread.run(JBossThread.java:122) +| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 158 | 135 | | getAndSet | 2014-02-16 09:15:08.349 | 2014-02-16 09:15:08.352 | COMPLETED | COMPLETED | | \xaced000574001e2a206d79206a6f6220657865637574696f6e20696420697320313334202a | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | (2 rows)
備考
- 再実行時にはpersistentUserDataがコピーされるようなので、データ量がでかい場合は気をつけた方がいいのかも
参考文献
Tags: jbatch