Thanks for your reply. Generally speaking, I can agree to prefer a O-oriented approach, but not in this case.
For the DB, I think it's much better a single INSERT .. SELECT than many INSERT .. VALUES, but we know Hibernate it's much more than a query generator.
The OO approach, correct me if I'm wrong, is something like this:
- iterate the collection of entities to be duplicated
- for each entity evict it to make it detached
- reset the id to unsaved-value and change the reference to parent entity
- save the new entity
- periodically flush the session and clear the cache (according to what is stated in chapter 13 for batch processing).
Given that, in my specific case, I still prefer a DB-oriented approach, if possible.
I'll add some detail:
*SQLQuery:
Code:
session.createSQLQuery("any SQL").executeUpdate();
gives the error:
Code:
java.lang.UnsupportedOperationException: Update queries only supported through HQL
at org.hibernate.impl.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:753)
...
*Named parameter:
Code:
session.createQuery( "insert into PriceListRows (priceList, area, price) select :toPriceList, p.area, p.price from PriceListRows p where p.priceList.id = :fromPriceListId" ).setEntity("toPriceList", priceList).setLong("fromPriceListId", priceListId).executeUpdate();
gives the error:
Code:
org.hibernate.QueryException: number of select types did not match those for insert [insert into PriceListRows (priceList, area, price) select :toPriceList, p.area, p.price from PriceListRows p where p.priceList.id = :fromPriceListId]
at org.hibernate.hql.ast.tree.IntoClause.validateTypes(IntoClause.java:92)
at org.hibernate.hql.ast.tree.InsertStatement.validate(InsertStatement.java:34)
at org.hibernate.hql.ast.HqlSqlWalker.postProcessInsert(HqlSqlWalker.java:600)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.insertStatement(HqlSqlBaseWalker.java:491)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:253)
at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:218)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:158)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:109)
...
*Literal:
if I try:
Code:
session.createQuery( "insert into PriceListRows (priceList.id, area, price) select " + toPriceListId + ", p.area, p.price from PriceListRows p where p.priceList.id = :fromPriceListId" ).setLong("fromPriceListId", priceListId).executeUpdate();
I get:
Code:
org.hibernate.QueryException: could not resolve property: of: model.PriceListRows [insert into PriceListRows (priceList.id, area, price) select 17, p.area, p.price from PriceListRows p where p.priceList.id = :fromPriceListId]
at org.hibernate.persister.entity.AbstractPropertyMapping.throwPropertyException(AbstractPropertyMapping.java:43)
at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:37)
at org.hibernate.persister.entity.AbstractEntityPersister.getSubclassPropertyTableNumber(AbstractEntityPersister.java:1282)
at org.hibernate.hql.ast.tree.IntoClause.isSuperclassProperty(IntoClause.java:184)
at org.hibernate.hql.ast.tree.IntoClause.visitPropertySpecNodes(IntoClause.java:143)
at org.hibernate.hql.ast.tree.IntoClause.initializeColumns(IntoClause.java:125)
at org.hibernate.hql.ast.tree.IntoClause.initialize(IntoClause.java:37)
...
Am I missing something obvious? I re-checked the documentation and seems the correct syntax to me, but I'm evidently wrong...