Hibernate unable to instantiate default tuplizer - cannot find getter - java

I'm trying to use Hibernate to persist a class that looks like this:
public class Item implements Serializable, Comparable<Item> {
// Item id
private Integer id;
// Description of item in inventory
private String description;
// Number of items described by this inventory item
private int count;
//Category item belongs to
private String category;
// Date item was purchased
private GregorianCalendar purchaseDate;
public Item() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public GregorianCalendar getPurchaseDate() {
return purchaseDate;
}
public void setPurchasedate(GregorianCalendar purchaseDate) {
this.purchaseDate = purchaseDate;
}
My Hibernate mapping file contains the following:
<property name="puchaseDate" type="java.util.GregorianCalendar">
<column name="purchase_date"></column>
</property>
When I try to run, I get error messages indicating there is no getter function for the purchaseDate attribute:
577 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - Using Hibernate built-in connection pool (not for production use!)
577 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - Hibernate connection pool size: 20
577 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - autocommit mode: false
592 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://localhost:3306/home_inventory
592 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - connection properties: {user=root, password=****}
1078 [main] INFO org.hibernate.cfg.SettingsFactory - RDBMS: MySQL, version: 5.1.45
1078 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC driver: MySQL-AB JDBC Driver, version: mysql-connector-java-5.1.12 ( Revision: ${bzr.revision-id} )
1103 [main] INFO org.hibernate.dialect.Dialect - Using dialect: org.hibernate.dialect.MySQLDialect
1107 [main] INFO org.hibernate.engine.jdbc.JdbcSupportLoader - Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
1109 [main] INFO org.hibernate.transaction.TransactionFactoryFactory - Using default transaction strategy (direct JDBC transactions)
1110 [main] INFO org.hibernate.transaction.TransactionManagerLookupFactory - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
1110 [main] INFO org.hibernate.cfg.SettingsFactory - Automatic flush during beforeCompletion(): disabled
1110 [main] INFO org.hibernate.cfg.SettingsFactory - Automatic session close at end of transaction: disabled
1110 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC batch size: 15
1110 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC batch updates for versioned data: disabled
1111 [main] INFO org.hibernate.cfg.SettingsFactory - Scrollable result sets: enabled
1111 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC3 getGeneratedKeys(): enabled
1111 [main] INFO org.hibernate.cfg.SettingsFactory - Connection release mode: auto
1111 [main] INFO org.hibernate.cfg.SettingsFactory - Maximum outer join fetch depth: 2
1111 [main] INFO org.hibernate.cfg.SettingsFactory - Default batch fetch size: 1
1111 [main] INFO org.hibernate.cfg.SettingsFactory - Generate SQL with comments: disabled
1111 [main] INFO org.hibernate.cfg.SettingsFactory - Order SQL updates by primary key: disabled
1111 [main] INFO org.hibernate.cfg.SettingsFactory - Order SQL inserts for batching: disabled
1112 [main] INFO org.hibernate.cfg.SettingsFactory - Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
1113 [main] INFO org.hibernate.hql.ast.ASTQueryTranslatorFactory - Using ASTQueryTranslatorFactory
1113 [main] INFO org.hibernate.cfg.SettingsFactory - Query language substitutions: {}
1113 [main] INFO org.hibernate.cfg.SettingsFactory - JPA-QL strict compliance: disabled
1113 [main] INFO org.hibernate.cfg.SettingsFactory - Second-level cache: enabled
1113 [main] INFO org.hibernate.cfg.SettingsFactory - Query cache: disabled
1113 [main] INFO org.hibernate.cfg.SettingsFactory - Cache region factory : org.hibernate.cache.impl.NoCachingRegionFactory
1113 [main] INFO org.hibernate.cfg.SettingsFactory - Optimize cache for minimal puts: disabled
1114 [main] INFO org.hibernate.cfg.SettingsFactory - Structured second-level cache entries: disabled
1117 [main] INFO org.hibernate.cfg.SettingsFactory - Echoing all SQL to stdout
1118 [main] INFO org.hibernate.cfg.SettingsFactory - Statistics: disabled
1118 [main] INFO org.hibernate.cfg.SettingsFactory - Deleted entity synthetic identifier rollback: disabled
1118 [main] INFO org.hibernate.cfg.SettingsFactory - Default entity-mode: pojo
1118 [main] INFO org.hibernate.cfg.SettingsFactory - Named query checking : enabled
1118 [main] INFO org.hibernate.cfg.SettingsFactory - Check Nullability in Core (should be disabled when Bean Validation is on): enabled
1151 [main] INFO org.hibernate.impl.SessionFactoryImpl - building session factory
org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer]
at org.hibernate.tuple.entity.EntityTuplizerFactory.constructTuplizer(EntityTuplizerFactory.java:110)
at org.hibernate.tuple.entity.EntityTuplizerFactory.constructDefaultTuplizer(EntityTuplizerFactory.java:135)
at org.hibernate.tuple.entity.EntityEntityModeToTuplizerMapping.<init>(EntityEntityModeToTuplizerMapping.java:80)
at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:323)
at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:475)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:133)
at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:84)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:295)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1385)
at service.HibernateSessionFactory.currentSession(HibernateSessionFactory.java:53)
at service.ItemSvcHibImpl.generateReport(ItemSvcHibImpl.java:78)
at service.test.ItemSvcTest.testGenerateReport(ItemSvcTest.java:226)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:164)
at junit.framework.TestCase.runBare(TestCase.java:130)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:120)
at junit.framework.TestSuite.runTest(TestSuite.java:230)
at junit.framework.TestSuite.run(TestSuite.java:225)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.hibernate.tuple.entity.EntityTuplizerFactory.constructTuplizer(EntityTuplizerFactory.java:107)
... 29 more
Caused by: org.hibernate.PropertyNotFoundException: Could not find a getter for puchaseDate in class domain.Item
at org.hibernate.property.BasicPropertyAccessor.createGetter(BasicPropertyAccessor.java:328)
at org.hibernate.property.BasicPropertyAccessor.getGetter(BasicPropertyAccessor.java:321)
at org.hibernate.mapping.Property.getGetter(Property.java:304)
at org.hibernate.tuple.entity.PojoEntityTuplizer.buildPropertyGetter(PojoEntityTuplizer.java:299)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:158)
at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:77)
... 34 more
I'm new to Hibernate, so I don't know all the ins and outs, but I do have the getter and setter for the purchaseDate attribute. I don't know what I'm missing here - does anyone else?

It came to me once without any typos. I've added javassist.jar to classpath and it solved the problem.

Further on down the stack trace, it says this:
missing a getter for puchaseDate
You might want to check for typos ;) You're missing an R and setPurchasedate should be setPurchaseDate

It looks like the problem is probably in the capitalization: setPurchasedate() should be setPurchaseDate() (with a capital "D").

If it can help someone:
In my case there were errors in my mapping files. Classes were not referenced by their full package names. I did this mistake because I generated the mappings when my bean classes belonged to the default package (hence no package name; e.g.: Order instead of com.mypackage.Order) and then I moved my bean classes to package (in the example com.mypackage). Unfortunately mapping files did not changed accordingly with the new package definition.
My hint is redo Hibernate reverse engineering and see what it produces, comparing it with your current mapping files.

Pay attention to method name,It is case sensitive!
In my case,it could not recognize getter very well; my property name was uId and I used getUId name for getter name and when I changed it to getuId problem solved!

I included java assit.jar and it worked
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>

I experienced the
Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer]
because I had a momentary lapse of donkeyness when renaming a field on a POJO that I had previously mapped.
I changed the Java attribute name with my trusty IDE refactor hotkey, which does not also change the getter & setter method names. I changed the getter (because it caught my attention with its #Column annotation that I also needed to address because the table column name was changing).
I neglected, however, to change the setter, and that was the cause of the error.

Related

Java.Util.Date Query Problem with JPA and Hibernates Binding Parameter

I'm currently working with Springboot. now I want to query data by Java.util.date via JpaRepository and I have the following code in my interface.
List<MyEnity> findByDate(Date date);
I use Java.util.date and I have a personal reason that I couldn't change to java.time. I've ensured that
MyEntity Class in date field has TemporalType.DATE like this
#Temporal(TemporalType.DATE) private Date date;
and also the date field in MySQL is also date type
enter image description here
I tried to use the findByDate(Date date) method above and the date paramter in the method is obviously exist in my database but I always get an Empty List...
The other methods like findByName(String name) or findAll() work just fine.
I've tried to log the SQL statement from hibernate and I found that the binding parameter [DATE] might be in a different format? in my db is 'yyyy-mm-dd'
here is a log where I query with id and date. and at the bottom of the log I notice that the Id is binded with query statement, but date won't
2563-04-10 12:18:54.649 [restartedMain] INFO o.s.b.d.a.ConditionEvaluationDeltaLoggingListener - Condition evaluation unchanged
2563-04-10 12:19:03.241 [http-nio-8080-exec-2] INFO o.a.c.c.C.[.[.[/api/productionplan] - Initializing Spring DispatcherServlet 'dispatcherServlet'
2563-04-10 12:19:03.282 [http-nio-8080-exec-2] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
2563-04-10 12:19:03.307 [http-nio-8080-exec-2] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 8 ms
2563-04-10 12:19:03.346 [http-nio-8080-exec-2] DEBUG org.hibernate.SQL -
select
planibtout0_.planibtoutid as planibto1_23_,
planibtout0_.ibtqty as ibtqty2_23_,
planibtout0_.finisheddate as finished3_23_,
planibtout0_.finishedshiftid as finished4_23_,
planibtout0_.itemid as itemid6_23_,
planibtout0_.itemclassid as itemclas5_23_,
planibtout0_.planfinishedgoodid as planfini7_23_,
planibtout0_.planibtoutlotid as planibto8_23_,
planibtout0_.planqty as planqty9_23_,
planibtout0_.producerstoreid as produce10_23_,
planibtout0_.sellerstoreid as sellers11_23_,
planibtout0_.updateat as updatea12_23_,
planibtout0_.updateby as updateb13_23_
from
planibtout planibtout0_
where
planibtout0_.producerstoreid=1117
and planibtout0_.finisheddate=?
2563-04-10 12:19:03.359 [http-nio-8080-exec-2] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [DATE] - [Tue Apr 15 00:00:00 ICT 1477]
2563-04-10 12:19:03.363 [http-nio-8080-exec-2] INFO c.n.t.t.s.c.SellerStoreController - -Data Not Found- No record found in database
here is my .yml properties
server:
port: 8080
servlet:
context-path: /api/xxx/
spring:
datasource:
url: jdbc:mysql://localhost:3306/xxx?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
driverClassName: com.mysql.cj.jdbc.Driver
username: xxx
password:
continueOnError: false
maximum-pool-size: 20
minimum-idle: 0
idle-timeout: 10000
connection-timeout: 10000
max-lifetime: 10000
auto-commit: true
jpa:
show-sql: false
hibernate:
ddlAuto: none
properties:
hibernate:
dialect: org.hibernate.dialect.MySQLDialect
format_sql: true
startDayInWeek: 2
logging:
level:
com.zaxxer.hikari.HikariConfig: DEBUG
com.ntt.th: DEBUG
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
Actually, there is no problem with Date binding that why query executed perfectly.
May be problem is Application Timezone and Database timezone is not matching.
You are sending DATE with IndoChina Timezone(ICT) Tue Apr 15 00:00:00 ICT 1477 but you are using serverTimezone=UTC(In JDBC Url) for database which means you are using UTC Timezone for Database.
So, you can change the timezone for database using serverTimezone=ICT to use IndoChina Timezone(ICT)

Hibernate creating table but not creating entry?

I am trying to test that my connection to Hibernate is working in my code so I set up a basic method to create a new entity in a table. When I run the code I don't see an error and when I first ran it Hibernate successfully created the table but the row is not being created in the table. Anyone know why this might be happening? Pasted User class and code to create below as well as logs.
public static void main(String[] args) {
Session session = SessionFactoryUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
User user = new User();
user.setPassword("abcd");
user.setStatus(UserStatus.OFFLINE);
user.setUserName("testuser");
session.save(user);
}
User class:
#Entity
#Table(name="USERS")
public class User {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="USER_ID")
private String userId;
#Column(name="USER_NAME")
private String userName;
#Column(name="PASSWORD")
private String password;
#Enumerated(EnumType.STRING)
#Column(name="STATUS")
private UserStatus status;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public UserStatus getStatus() {
return status;
}
public void setStatus(UserStatus status) {
this.status = status;
}
}
Logs:
[main] INFO org.hibernate.cfg.Environment - Hibernate 3.5.1-Final
[main] INFO org.hibernate.cfg.Environment - hibernate.properties not found
[main] INFO org.hibernate.cfg.Environment - Bytecode provider name : javassist
[main] INFO org.hibernate.cfg.Environment - using JDK 1.4 java.sql.Timestamp handling
[main] INFO org.hibernate.cfg.Configuration - configuring from resource: /hibernate.cfg.xml
[main] INFO org.hibernate.cfg.Configuration - Configuration resource: /hibernate.cfg.xml
[main] INFO org.hibernate.cfg.Configuration - Reading mappings from resource : messagingservice/db/User.hbm.xml
[main] INFO org.hibernate.cfg.HbmBinder - Mapping class: messagingservice.db.User -> USERS
[main] INFO org.hibernate.cfg.Configuration - Configured SessionFactory: null
[main] INFO org.hibernate.connection.DriverManagerConnectionProvider - Using Hibernate built-in connection pool (not for production use!)
[main] INFO org.hibernate.connection.DriverManagerConnectionProvider - Hibernate connection pool size: 20
[main] INFO org.hibernate.connection.DriverManagerConnectionProvider - autocommit mode: false
[main] INFO org.hibernate.connection.DriverManagerConnectionProvider - using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://localhost/CAREZONE_MESSAGING
[main] INFO org.hibernate.connection.DriverManagerConnectionProvider - connection properties: {user=hibernate, password=****}
[main] INFO org.hibernate.cfg.SettingsFactory - RDBMS: MySQL, version: 5.7.11-log
[main] INFO org.hibernate.cfg.SettingsFactory - JDBC driver: MySQL Connector Java, version: mysql-connector-java-5.1.37 ( Revision: 09940f05b4c98150f352e787a2549f11a2e9da93 )
[main] INFO org.hibernate.dialect.Dialect - Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
[main] INFO org.hibernate.transaction.TransactionFactoryFactory - Transaction strategy: org.hibernate.transaction.JDBCTransactionFactory
[main] INFO org.hibernate.transaction.TransactionManagerLookupFactory - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
[main] INFO org.hibernate.cfg.SettingsFactory - Automatic flush during beforeCompletion(): disabled
[main] INFO org.hibernate.cfg.SettingsFactory - Automatic session close at end of transaction: disabled
[main] INFO org.hibernate.cfg.SettingsFactory - JDBC batch size: 15
[main] INFO org.hibernate.cfg.SettingsFactory - JDBC batch updates for versioned data: disabled
[main] INFO org.hibernate.cfg.SettingsFactory - Scrollable result sets: enabled
[main] INFO org.hibernate.cfg.SettingsFactory - JDBC3 getGeneratedKeys(): enabled
[main] INFO org.hibernate.cfg.SettingsFactory - Connection release mode: auto
[main] INFO org.hibernate.cfg.SettingsFactory - Maximum outer join fetch depth: 2
[main] INFO org.hibernate.cfg.SettingsFactory - Default batch fetch size: 1
[main] INFO org.hibernate.cfg.SettingsFactory - Generate SQL with comments: disabled
[main] INFO org.hibernate.cfg.SettingsFactory - Order SQL updates by primary key: disabled
[main] INFO org.hibernate.cfg.SettingsFactory - Order SQL inserts for batching: disabled
[main] INFO org.hibernate.cfg.SettingsFactory - Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
[main] INFO org.hibernate.hql.ast.ASTQueryTranslatorFactory - Using ASTQueryTranslatorFactory
[main] INFO org.hibernate.cfg.SettingsFactory - Query language substitutions: {}
[main] INFO org.hibernate.cfg.SettingsFactory - JPA-QL strict compliance: disabled
[main] INFO org.hibernate.cfg.SettingsFactory - Second-level cache: enabled
[main] INFO org.hibernate.cfg.SettingsFactory - Query cache: disabled
[main] INFO org.hibernate.cfg.SettingsFactory - Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge
[main] INFO org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge - Cache provider: org.hibernate.cache.HashtableCacheProvider
[main] INFO org.hibernate.cfg.SettingsFactory - Optimize cache for minimal puts: disabled
[main] INFO org.hibernate.cfg.SettingsFactory - Structured second-level cache entries: disabled
[main] INFO org.hibernate.cfg.SettingsFactory - Statistics: disabled
[main] INFO org.hibernate.cfg.SettingsFactory - Deleted entity synthetic identifier rollback: disabled
[main] INFO org.hibernate.cfg.SettingsFactory - Default entity-mode: pojo
[main] INFO org.hibernate.cfg.SettingsFactory - Named query checking : enabled
[main] INFO org.hibernate.cfg.SettingsFactory - Check Nullability in Core (should be disabled when Bean Validation is on): enabled
[main] INFO org.hibernate.impl.SessionFactoryImpl - building session factory
[main] INFO org.hibernate.impl.SessionFactoryObjectFactory - Not binding factory to JNDI, no JNDI name configured
[main] INFO org.hibernate.tool.hbm2ddl.SchemaExport - Running hbm2ddl schema export
[main] INFO org.hibernate.tool.hbm2ddl.SchemaExport - exporting generated schema to database
[main] INFO org.hibernate.tool.hbm2ddl.SchemaExport - schema export complete
You are not committing your transaction. You need to do:
public static void main(String[] args) {
Session session = SessionFactoryUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setPassword("abcd");
user.setStatus(UserStatus.OFFLINE);
user.setUserName("testuser");
session.save(user);
tx.commit();
session.close();
}

Docx4J is not replacing placeholders

I am trying to replace a simple 'Place Holderin MS Word 2007 usingDocx4J. I created the placeholder byReference > Insert Citation > Add New Placeholder`
Below is my Docx4J code
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBElement;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.Text;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* #author Yohan
*/
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
new Main();
}
public Main()
{
try
{
WordprocessingMLPackage template = getTemplate("C:/Users/Yohan/Desktop/Yohan.docx");
replacePlaceholder(template,"Plane","Placeholder1");
writeDocxToStream(template,"C:/Users/Yohan/Desktop/Yohan2.docx");
System.out.println("Operation Completed");
}
catch(Exception e)
{
e.printStackTrace();
}
}
private WordprocessingMLPackage getTemplate(String name) throws Docx4JException, FileNotFoundException {
WordprocessingMLPackage template = WordprocessingMLPackage.load(new FileInputStream(new File(name)));
return template;
}
private static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {
List<Object> result = new ArrayList<Object>();
if (obj instanceof JAXBElement) obj = ((JAXBElement<?>) obj).getValue();
if (obj.getClass().equals(toSearch))
result.add(obj);
else if (obj instanceof ContentAccessor) {
List<?> children = ((ContentAccessor) obj).getContent();
for (Object child : children) {
result.addAll(getAllElementFromObject(child, toSearch));
}
}
return result;
}
private void replacePlaceholder(WordprocessingMLPackage template, String name, String placeholder ) {
List<Object> texts = getAllElementFromObject(template.getMainDocumentPart(), Text.class);
for (Object text : texts) {
Text textElement = (Text) text;
if (textElement.getValue().equals(placeholder)) {
textElement.setValue(name);
}
}
}
private void writeDocxToStream(WordprocessingMLPackage template, String target) throws IOException, Docx4JException {
File f = new File(target);
template.save(f);
}
}
This generated the below in Netbeans console.
[main] INFO org.docx4j.jaxb.Context - java.vendor=Oracle Corporation
[main] INFO org.docx4j.jaxb.Context - java.version=1.8.0_05
[main] INFO org.docx4j.jaxb.Context - No MOXy JAXB config found; assume not intended..
[main] INFO org.docx4j.jaxb.NamespacePrefixMapperUtils - Using NamespacePrefixMapperSunInternal, which is suitable for Java 6
[main] INFO org.docx4j.jaxb.Context - Using Java 6/7 JAXB implementation
[main] INFO org.docx4j.jaxb.Context - Not using MOXy; using com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl
[main] WARN org.docx4j.utils.ResourceUtils - Couldn't get resource: docx4j.properties
[main] WARN org.docx4j.Docx4jProperties - Couldn't find/read docx4j.properties; docx4j.properties not found via classloader.
[main] INFO org.docx4j.XmlUtils - Using com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
[main] INFO org.docx4j.XmlUtils - Using com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
[main] INFO org.docx4j.openpackaging.contenttype.ContentTypeManager - Detected WordProcessingML package
[main] INFO org.docx4j.openpackaging.io3.Load3 - Instantiated package of type org.docx4j.openpackaging.packages.WordprocessingMLPackage
[main] INFO org.docx4j.utils.XPathFactoryUtil - xpath implementation: org.apache.xpath.jaxp.XPathFactoryImpl
[main] INFO org.docx4j.openpackaging.io.Load - Found a CustomXmlPart, named /customXml/item1.xml
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - Lazily unmarshalling /customXml/itemProps1.xml
[main] INFO org.docx4j.openpackaging.io.Load - Identified/registered ds:itemId {2da45ade-e2fe-4251-9c73-a623aa57ebb0}
[main] INFO org.docx4j.openpackaging.io3.Load3 - package read; elapsed time: 10932 ms
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - Lazily unmarshalling /word/document.xml
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPartXPathAware - For org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart, unmarshall via binder
[main] INFO org.docx4j.openpackaging.contenttype.ContentTypeManager - marshalling org.docx4j.openpackaging.contenttype.ContentTypeManager ...
[main] INFO org.docx4j.jaxb.NamespacePrefixMapperUtils - Using NamespacePrefixMapperSunInternal, which is suitable for Java 6
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - marshalling org.docx4j.openpackaging.parts.relationships.RelationshipsPart
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - marshalling org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - marshalling org.docx4j.openpackaging.parts.relationships.RelationshipsPart
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - marshalling org.docx4j.openpackaging.parts.WordprocessingML.BibliographyPart
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - marshalling org.docx4j.openpackaging.parts.relationships.RelationshipsPart
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - marshalling org.docx4j.openpackaging.parts.CustomXmlDataStoragePropertiesPart
[main] INFO org.docx4j.openpackaging.io3.Save - ...Done!
Operation Completed
However in Yohan2.docx, nothing is changed, it is a pure copy of Yohan.docx. What have I done wrong here?
UPDATE
I tested the MERGEFIELD example from the GITHUB but it also didn't work. Below is the output printed in console
[main] INFO org.docx4j.jaxb.Context - java.vendor=Oracle Corporation
[main] INFO org.docx4j.jaxb.Context - java.version=1.8.0_05
[main] INFO org.docx4j.jaxb.Context - No MOXy JAXB config found; assume not intended..
[main] INFO org.docx4j.jaxb.NamespacePrefixMapperUtils - Using NamespacePrefixMapperSunInternal, which is suitable for Java 6
[main] INFO org.docx4j.jaxb.Context - Using Java 6/7 JAXB implementation
[main] INFO org.docx4j.jaxb.Context - Not using MOXy; using com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl
[main] WARN org.docx4j.utils.ResourceUtils - Couldn't get resource: docx4j.properties
[main] WARN org.docx4j.Docx4jProperties - Couldn't find/read docx4j.properties; docx4j.properties not found via classloader.
[main] INFO org.docx4j.XmlUtils - Using com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
[main] INFO org.docx4j.XmlUtils - Using com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
[main] INFO org.docx4j.openpackaging.contenttype.ContentTypeManager - Detected WordProcessingML package
[main] INFO org.docx4j.openpackaging.io3.Load3 - Instantiated package of type org.docx4j.openpackaging.packages.WordprocessingMLPackage
[main] INFO org.docx4j.utils.XPathFactoryUtil - xpath implementation: org.apache.xpath.jaxp.XPathFactoryImpl
[main] WARN org.docx4j.openpackaging.contenttype.ContentTypeManager - DefaultPart used for part '/word/stylesWithEffects.xml' of content type 'application/vnd.ms-word.stylesWithEffects+xml'
[main] INFO org.docx4j.openpackaging.io3.Load3 - package read; elapsed time: 14766 ms
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - Lazily unmarshalling /word/document.xml
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPartXPathAware - For org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart, unmarshall via binder
[main] INFO org.docx4j.model.fields.merge.MailMerger - Found 9 fields
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'kundenname'
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'kundenname'
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'kundenname'
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'Kundenname'
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'KunDenName'
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'KUNDENNAME'
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'Kundenstrasse'
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'yourdate'
[main] INFO org.docx4j.model.fields.DateFormatInferencer - Infering dates based using International formats
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'yournumber'
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - Lazily unmarshalling /word/settings.xml
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPartXPathAware - For org.docx4j.openpackaging.parts.WordprocessingML.DocumentSettingsPart, unmarshall via binder
[main] INFO org.docx4j.openpackaging.contenttype.ContentTypeManager - marshalling org.docx4j.openpackaging.contenttype.ContentTypeManager ...
[main] INFO org.docx4j.jaxb.NamespacePrefixMapperUtils - Using NamespacePrefixMapperSunInternal, which is suitable for Java 6
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - marshalling org.docx4j.openpackaging.parts.relationships.RelationshipsPart
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - marshalling org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - marshalling org.docx4j.openpackaging.parts.relationships.RelationshipsPart
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - marshalling org.docx4j.openpackaging.parts.WordprocessingML.DocumentSettingsPart
[main] WARN org.docx4j.openpackaging.parts.WordprocessingML.DocumentSettingsPart -
[main] INFO org.docx4j.openpackaging.io3.Save - ...Done!
[main] INFO org.docx4j.model.fields.merge.MailMerger - Found 9 fields
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'kundenname'
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'kundenname'
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'kundenname'
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'Kundenname'
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'KunDenName'
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'KUNDENNAME'
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'Kundenstrasse'
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'yourdate'
[main] INFO org.docx4j.model.fields.merge.MailMerger - Key: 'yournumber'
[main] INFO org.docx4j.openpackaging.contenttype.ContentTypeManager - marshalling org.docx4j.openpackaging.contenttype.ContentTypeManager ...
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - marshalling org.docx4j.openpackaging.parts.relationships.RelationshipsPart
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - marshalling org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - marshalling org.docx4j.openpackaging.parts.relationships.RelationshipsPart
[main] INFO org.docx4j.openpackaging.parts.JaxbXmlPart - marshalling org.docx4j.openpackaging.parts.WordprocessingML.DocumentSettingsPart
[main] WARN org.docx4j.openpackaging.parts.WordprocessingML.DocumentSettingsPart -
[main] INFO org.docx4j.openpackaging.io3.Save - ...Done!
A placeholder inserted via Reference > Insert Citation > Add New Placeholder results in something like:
<w:sdt>
<w:sdtPr>
<w:id w:val="-963732549"/>
<w:citation/>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:fldChar w:fldCharType="begin"/>
</w:r>
<w:r>
<w:rPr>
<w:lang w:val="en-AU"/>
</w:rPr>
<w:instrText xml:space="preserve"> CITATION PL1 \l 3081 </w:instrText>
</w:r>
<w:r>
<w:fldChar w:fldCharType="separate"/>
</w:r>
<w:r>
<w:rPr>
<w:noProof/>
<w:lang w:val="en-AU"/>
</w:rPr>
<w:t>(PL1)</w:t>
</w:r>
<w:r>
<w:fldChar w:fldCharType="end"/>
</w:r>
</w:sdtContent>
</w:sdt>
ie a CITATION field wrapped in a content control.
docx4j has an API for replacing MERGEFIELD and DOCPROPERTY fields, but not CITATION fields.
Is there a particular reason you are trying to use a CITATION field?
If you can swap to MERGEFIELD or DOCPROPERTY field, I'd do that. Otherwise, you could examine docx4j's code for handling those, and adapt it to handling CITATION.
Place Holder in Insert > Quick Parts > Field
Select MergeField
Copy merge field name as appears in the document together with the arrow characters to your code.
replacePlaceholder(template,"Plane","placeholdernamewitharrowcharacters");

Could not prepare statement while saving via entity manager

I've got the following error:
07:27:02,736 INFO Version:37 - HCANN000001: Hibernate Commons Annotations {4.0.1.Final}
07:27:02,745 INFO Version:41 - HHH000412: Hibernate Core {4.2.0.Final}
07:27:02,755 INFO Environment:239 - HHH000206: hibernate.properties not found
07:27:02,757 INFO Environment:342 - HHH000021: Bytecode provider name : javassist
07:27:02,799 INFO Configuration:1933 - HHH000043: Configuring from resource: ./hibernate.cfg.xml
07:27:02,799 INFO Configuration:1952 - HHH000040: Configuration resource: ./hibernate.cfg.xml
07:27:02,888 WARN DTDEntityResolver:74 - HHH000223: Recognized obsolete hibernate namespace http://hibernate.sourceforge.net/. Use namespace http://www.hibernate.org/dtd/ instead. Refer to Hibernate 3.6 Migration Guide!
07:27:02,960 INFO Configuration:2074 - HHH000041: Configured SessionFactory: null
07:27:03,677 INFO DriverManagerConnectionProviderImpl:98 - HHH000402: Using Hibernate built-in connection pool (not for production use!)
07:27:03,712 INFO DriverManagerConnectionProviderImpl:134 - HHH000115: Hibernate connection pool size: 20
07:27:03,713 INFO DriverManagerConnectionProviderImpl:137 - HHH000006: Autocommit mode: false
07:27:03,713 INFO DriverManagerConnectionProviderImpl:151 - HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost/ForBook]
07:27:03,713 INFO DriverManagerConnectionProviderImpl:156 - HHH000046: Connection properties: {user=root, password=****}
07:27:05,539 INFO Dialect:128 - HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
07:27:05,570 INFO LobCreatorBuilder:94 - HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
07:27:05,608 INFO TransactionFactoryInitiator:68 - HHH000399: Using default transaction strategy (direct JDBC transactions)
07:27:05,633 INFO ASTQueryTranslatorFactory:48 - HHH000397: Using ASTQueryTranslatorFactory
07:27:05,822 INFO Version:39 - HSEARCH000034: Hibernate Search 4.3.0.Alpha1
07:27:05,988 WARN ConfigContext:301 - HSEARCH000075: Configuration setting hibernate.search.lucene_version was not specified, using LUCENE_CURRENT.
07:27:06,703 INFO SchemaExport:343 - HHH000227: Running hbm2ddl schema export
07:27:06,704 DEBUG SchemaExport:353 - Import file not found: /import.sql
07:27:06,706 DEBUG SQL:104 - alter table BEE drop foreign key FK100622C0E7E16
07:27:07,463 DEBUG SQL:104 - drop table if exists BEE
07:27:07,829 DEBUG SQL:104 - drop table if exists HONEY
07:27:07,999 DEBUG SQL:104 - create table BEE (id integer not null auto_increment, city varchar(255), street varchar(255), myEnum varchar(255), nameOfBee varchar(255), honey_id integer not null, primary key (id))
07:27:08,533 DEBUG SQL:104 - create table HONEY (honey_id integer not null auto_increment, NAME_OF_HONEY varchar(255), taste varchar(255), primary key (honey_id))
07:27:08,955 DEBUG SQL:104 - alter table BEE add index FK100622C0E7E16 (honey_id), add constraint FK100622C0E7E16 foreign key (honey_id) references HONEY (honey_id)
07:27:10,344 INFO SchemaExport:405 - HHH000230: Schema export complete
07:27:10,667 INFO DriverManagerConnectionProviderImpl:98 - HHH000402: Using Hibernate built-in connection pool (not for production use!)
07:27:10,680 INFO DriverManagerConnectionProviderImpl:134 - HHH000115: Hibernate connection pool size: 20
07:27:10,681 INFO DriverManagerConnectionProviderImpl:137 - HHH000006: Autocommit mode: true
07:27:10,681 INFO DriverManagerConnectionProviderImpl:151 - HHH000401: using driver [org.hsqldb.jdbcDriver] at URL [jdbc:hsqldb:.]
07:27:10,681 INFO DriverManagerConnectionProviderImpl:156 - HHH000046: Connection properties: {user=sa, password=****, autocommit=true, release_mode=auto}
07:27:10,907 INFO Dialect:128 - HHH000400: Using dialect: org.hibernate.dialect.HSQLDialect
07:27:10,909 INFO LobCreatorBuilder:94 - HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
07:27:10,910 INFO TransactionFactoryInitiator:73 - HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory
07:27:10,910 INFO ASTQueryTranslatorFactory:48 - HHH000397: Using ASTQueryTranslatorFactory
07:27:10,924 WARN ConfigContext:301 - HSEARCH000075: Configuration setting hibernate.search.lucene_version was not specified, using LUCENE_CURRENT.
07:27:10,947 INFO SchemaExport:343 - HHH000227: Running hbm2ddl schema export
07:27:10,948 DEBUG SchemaExport:353 - Import file not found: /import.sql
07:27:10,948 DEBUG SQL:104 - alter table BEE drop constraint FK100622C0E7E16
07:27:10,950 ERROR SchemaExport:425 - HHH000389: Unsuccessful: alter table BEE drop constraint FK100622C0E7E16
07:27:10,950 ERROR SchemaExport:426 - Table not found: BEE in statement [alter table BEE]
07:27:10,950 DEBUG SQL:104 - drop table BEE if exists
07:27:10,951 DEBUG SQL:104 - drop table HONEY if exists
07:27:10,951 DEBUG SQL:104 - create table BEE (id integer generated by default as identity (start with 1), city varchar(255), street varchar(255), myEnum varchar(255), nameOfBee varchar(255), honey_id integer not null, primary key (id))
07:27:10,953 DEBUG SQL:104 - create table HONEY (honey_id integer generated by default as identity (start with 1), NAME_OF_HONEY varchar(255), taste varchar(255), primary key (honey_id))
07:27:10,953 DEBUG SQL:104 - alter table BEE add constraint FK100622C0E7E16 foreign key (honey_id) references HONEY
07:27:10,956 INFO SchemaExport:405 - HHH000230: Schema export complete
07:27:11,190 DEBUG SQL:104 - insert into HONEY (honey_id, NAME_OF_HONEY, taste) values (null, ?, ?)
07:27:11,191 WARN SqlExceptionHelper:143 - SQL Error: -20, SQLState: IM001
07:27:11,191 ERROR SqlExceptionHelper:144 - This function is not supported
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not prepare statement
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1316)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:881)
at ua.hibernate_project.TestWork.main(TestWork.java:88)
Caused by: org.hibernate.exception.GenericJDBCException: could not prepare statement
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:188)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareStatement(StatementPreparerImpl.java:117)
at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:55)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2966)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3477)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:203)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:183)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:167)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:321)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:286)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:78)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:852)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:826)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:830)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:875)
... 1 more
Caused by: java.sql.SQLException: This function is not supported
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.Util.notSupported(Unknown Source)
at org.hsqldb.jdbc.jdbcConnection.prepareStatement(Unknown Source)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$2.doPrepare(StatementPreparerImpl.java:119)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:182)
... 22 more
While I try to work with entity manager (via Hibernate API all works good)
I can see entity manager tries to insert id, i.e. honey_id
DEBUG SQL:104 - insert into HONEY (honey_id, NAME_OF_HONEY, taste) values (null, ?, ?)
via Hibernate API I see follow
DEBUG SQL:104 - insert into HONEY (NAME_OF_HONEY, taste) values (?, ?)
My classes
Bee:
#Entity
#Table(name = "BEE")
public class Bee {
#ManyToOne
#JoinColumn(name = "honey_id", nullable = false)
private Honey honey;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String nameOfBee;
#Enumerated(EnumType.STRING)
private MyEnum myEnum = MyEnum.UNNORMAL;
#Embedded
private Address address;
Honey:
#Table(name = "HONEY")
#Entity
public class Honey {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "honey_id")
private int id;
#Column(name = "NAME_OF_HONEY")
private String nameOfHoney;
private String taste;
#OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.ALL }, mappedBy = "honey" )
private Set<Bee> bees;
Address:
#Embeddable
public class Address {
public Address() {}
TestWork:
public class TestWork {
private static SessionFactory sessionFactory;
private static EntityManagerFactory emf;
private Session session;
static{
Configuration configuration = new Configuration();
configuration.configure("./hibernate.cfg.xml");
ServiceRegistryBuilder serviceRegistryBuilder =
new ServiceRegistryBuilder().applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(serviceRegistryBuilder.buildServiceRegistry());
emf = Persistence.createEntityManagerFactory("hibernate-search-example");
}
public Session openSessionAndGetTransaction(){
session = sessionFactory.openSession();
session.getTransaction().begin();
return session;
}
public static EntityManager getEntityManager(){
return emf.createEntityManager();
}
public void commitAndCloseSession(){
session.getTransaction().commit();
session.close();
}
public static void main(String[] args) {
TestWork testWork = new TestWork();
EntityManager em = TestWork.getEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Address address = new Address("Dnipro", "K.Marksa");
Honey honeyFromForest = new Honey("FirstHoney","Very tasty");
Bee firstBee = new Bee();
firstBee.setAddress(address);
firstBee.setNameOfBee("I'm first Bee");
firstBee.setHoney(honeyFromForest);
Bee secondBee = new Bee();
secondBee.setAddress(address);
secondBee.setNameOfBee("I'm second Bee");
secondBee.setHoney(honeyFromForest);
Set<Bee> bees = new HashSet<Bee>();
bees.add(firstBee);
bees.add(secondBee);
honeyFromForest.setBees(bees);
em.persist(honeyFromForest);
em.persist(firstBee);
em.persist(secondBee);
}
Thank you for your help!

Hibernate batch size confusion

This program does tens of thousands of consecutive inserts one after the other. I've never used Hibernate before. I'm getting extremely slow performance (if I just connect and execute the SQL manually I am 10-12x quicker. My batch_size is set to 50 as per many hibernate tutorials.
Here is a log from a single insert - perhaps you could help me understand exactly what is happening:
START INSERT
11:02:56.121 [main] DEBUG org.hibernate.impl.SessionImpl - opened session at timestamp: 13106053761
11:02:56.121 [main] DEBUG o.h.transaction.JDBCTransaction - begin
11:02:56.121 [main] DEBUG org.hibernate.jdbc.ConnectionManager - opening JDBC connection
11:02:56.121 [main] TRACE o.h.c.DriverManagerConnectionProvider - total checked-out connections: 0
11:02:56.121 [main] TRACE o.h.c.DriverManagerConnectionProvider - using pooled JDBC connection, pool size: 0
11:02:56.121 [main] DEBUG o.h.transaction.JDBCTransaction - current autocommit status: false
11:02:56.121 [main] TRACE org.hibernate.jdbc.JDBCContext - after transaction begin
11:02:56.121 [main] TRACE org.hibernate.impl.SessionImpl - setting flush mode to: MANUAL
11:02:56.121 [main] TRACE o.h.e.def.DefaultLoadEventListener - loading entity: [com.xyzcompany.foo.edoi.ejb.msw000.MSW000Rec#component[keyW000]{keyW000=F000 ADSUFC}]
11:02:56.121 [main] TRACE o.h.e.def.DefaultLoadEventListener - creating new proxy for entity
11:02:56.122 [main] TRACE o.h.e.d.DefaultSaveOrUpdateEventListener - saving transient instance
11:02:56.122 [main] DEBUG o.h.e.def.AbstractSaveEventListener - generated identifier: component[keyW000]{keyW000=F000 ADSUFC}, using strategy: org.hibernate.id.CompositeNestedGeneratedValueGenerator
11:02:56.122 [main] TRACE o.h.e.def.AbstractSaveEventListener - saving [com.xyzcompany.foo.edoi.ejb.msw000.MSW000Rec#component[keyW000]{keyW000=F000 ADSUFC}]
11:02:56.123 [main] TRACE o.h.e.d.AbstractFlushingEventListener - flushing session
11:02:56.123 [main] DEBUG o.h.e.d.AbstractFlushingEventListener - processing flush-time cascades
11:02:56.123 [main] DEBUG o.h.e.d.AbstractFlushingEventListener - dirty checking collections
11:02:56.123 [main] TRACE o.h.e.d.AbstractFlushingEventListener - Flushing entities and processing referenced collections
11:02:56.125 [main] TRACE o.h.e.d.AbstractFlushingEventListener - Processing unreferenced collections
11:02:56.125 [main] TRACE o.h.e.d.AbstractFlushingEventListener - Scheduling collection removes/(re)creates/updates
11:02:56.126 [main] DEBUG o.h.e.d.AbstractFlushingEventListener - Flushed: 1 insertions, 0 updates, 0 deletions to 62 objects
11:02:56.126 [main] DEBUG o.h.e.d.AbstractFlushingEventListener - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
11:02:56.132 [main] TRACE o.h.e.d.AbstractFlushingEventListener - executing flush
11:02:56.132 [main] TRACE org.hibernate.jdbc.ConnectionManager - registering flush begin
11:02:56.132 [main] TRACE o.h.p.entity.AbstractEntityPersister - Inserting entity: [com.xyzcompany.foo.edoi.ejb.msw000.MSW000Rec#component[keyW000]{keyW000=F000 ADSUFC}]
11:02:56.132 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
11:02:56.132 [main] DEBUG org.hibernate.SQL - insert into MSW000 (W000_DATA_REC, W000_FILE_FLAGS, KEY_W000) values (?, ?, ?)
11:02:56.132 [main] TRACE org.hibernate.jdbc.AbstractBatcher - preparing statement
11:02:56.132 [main] TRACE o.h.p.entity.AbstractEntityPersister - Dehydrating entity: [com.xyzcompany.foo.edoi.ejb.msw000.MSW000Rec#component[keyW000]{keyW000=F000 ADSUFC}]
11:02:56.132 [main] TRACE org.hibernate.type.StringType - binding ' ADSUFCA ' to parameter: 1
11:02:56.132 [main] TRACE org.hibernate.type.StringType - binding ' ' to parameter: 2
11:02:56.132 [main] TRACE org.hibernate.type.StringType - binding 'F000 ADSUFC' to parameter: 3
11:02:56.132 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - Executing batch size: 1
11:02:56.133 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
11:02:56.133 [main] TRACE org.hibernate.jdbc.AbstractBatcher - closing statement
11:02:56.133 [main] TRACE org.hibernate.jdbc.ConnectionManager - registering flush end
11:02:56.133 [main] TRACE o.h.e.d.AbstractFlushingEventListener - post flush
11:02:56.133 [main] DEBUG o.h.transaction.JDBCTransaction - commit
11:02:56.133 [main] TRACE org.hibernate.impl.SessionImpl - automatically flushing session
11:02:56.133 [main] TRACE org.hibernate.jdbc.JDBCContext - before transaction completion
11:02:56.133 [main] TRACE org.hibernate.impl.SessionImpl - before transaction completion
11:02:56.133 [main] DEBUG o.h.transaction.JDBCTransaction - committed JDBC Connection
11:02:56.133 [main] TRACE org.hibernate.jdbc.JDBCContext - after transaction completion
11:02:56.133 [main] DEBUG org.hibernate.jdbc.ConnectionManager - transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
11:02:56.133 [main] TRACE org.hibernate.impl.SessionImpl - after transaction completion
11:02:56.133 [main] TRACE org.hibernate.impl.SessionImpl - closing session
11:02:56.133 [main] TRACE org.hibernate.jdbc.ConnectionManager - performing cleanup
11:02:56.133 [main] DEBUG org.hibernate.jdbc.ConnectionManager - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
11:02:56.133 [main] TRACE o.h.c.DriverManagerConnectionProvider - returning connection to pool, pool size: 1
11:02:56.133 [main] TRACE org.hibernate.jdbc.JDBCContext - after transaction completion
11:02:56.133 [main] DEBUG org.hibernate.jdbc.ConnectionManager - transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
11:02:56.134 [main] TRACE org.hibernate.impl.SessionImpl - after transaction completion
FINISH INSERT
When you call session.save(), hibernate will generate an INSERT SQL. This INSERT SQL will be appended to be issued to the DB during flushing (i.e session.flush()) .
During flushing, if hibernate.jdbc.batch_size is set to some non-zero value, Hibernate will use the batching feature introduced in the JDBC2 API to issue the batch insert SQL to the DB .
For example , if you save() 100 records and your hibernate.jdbc.batch_size is set to 50. During flushing, instead of issue the following SQL 100 times :
insert into TableA (id , fields) values (1, 'val1');
insert into TableA (id , fields) values (2, 'val2');
insert into TableA (id , fields) values (3, 'val3');
.........................
insert into TableA (id , fields) values (100, 'val100');
Hiberate will group them in batches of 50 , and only issue 2 SQL to the DB, like this:
insert into TableA (id , fields) values (1, 'val1') , (2, 'val2') ,(3, 'val3') ,(4, 'val4') ,......,(50, 'val50')
insert into TableA (id , fields) values (51, 'val51') , (52, 'val52') ,(53, 'val53') ,(54, 'val54'),...... ,(100, 'val100')
Please note that Hibernate would disable insert batching at the JDBC level transparently if the primary key of the inserting table isGenerationType.Identity.
From your log: you save() only one record and then flush(), so there is only one appending INSERT SQL to be processed for every flush. That's why Hibernate cannot help you to batch inserting as there is only one INSERT SQL to be processed. You should save() up to the certain amount of records before calling flush() instead of calling flush() for every save().
The best practise of batch inserting is something like this:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<888888; i++ ) {
TableA record = new TableA();
record.setXXXX();
session.save(record)
if ( i % 50 == 0 ) { //50, same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();
You save and flush the records batch by batch. In the end of each batch you should clear the persistence context to release some memory to prevent memory exhaustion as every persistent object is placed into the first level cache (your JVM's memory). You could also disable the second-level cache to reduce the unnecessary overhead.
Reference:
Official Hibernate Documentation : Chapter 14. Batch processing
Hibernate Batch Processing – Why you may not be using it. (Even if you think you are)
If you must use hibernate for huge batch jobs StatelessSession is the way to go. It strips things down to the most basic converting-objects-to-SQL-statements mapping and eliminates all of the overhead of the ORM features you're not using when just cramming rows into the DB wholesale.
It would also be much easier to make suggestions on your actual code than the log :)
11:02:56.133 [main] DEBUG o.h.transaction.JDBCTransaction - commit
This is saying that the database is committing after every insert. Ensure you are not committing your transaction / closing your session inside the insert loop. Do this once at the end instead.

Categories

Resources