Ruben Laguna’s blog

ClassCastException: JAXBContextImp to JAXBContext With Woodstox and NetBeans

If you are getting

1
2
3
4
5
6
7

1
2
3
4
5
6
7
<span class='line'>java.lang.ClassCastException: com.sun.xml.bind.v2.runtime.JAXBContextImpl cannot be cast to javax.xml.bind.JAXBContext
</span><span class='line'>        at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:145)
</span><span class='line'>        at javax.xml.bind.ContextFinder.find(ContextFinder.java:277)
</span><span class='line'>        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:372)
</span><span class='line'>        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:337)
</span><span class='line'>        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:244)
</span><span class='line'>        at com.rubenlaguna.en4j.mainmodule.ImportEvernoteFile.actionPerformed(ImportEvernoteFile.java:65)</span>

and you are using woodstox be sure to check the DevFaqModuleCCE. This could happen when you have Netbeans Platform Application with a module containing woodstox but also including JAXB 2.1 in the module dependencies for the application.

Git: Error Pushing via HTTP (Return Code 22)

If you get a

error: Cannot access URL http://github.com/xxxxxxx/, return code 22

when trying to push changes to a git repository via HTTP.

This is probably because you are using an HTTP proxy to access the repo and that proxy doesn’t support WebDAV HTTP methods (especially PROPFIND). So when git issues a PROPFIND the http proxy answers back with a 500 Internal Server Error or something like that.

It seems that PROPFIND is absolutely required so if you can use git:// directly or use a HTTP proxy which supports PROPFIND. Then I think the only option left is try use CONNECT in the proxy.

OpenJPA: Generated SQL Contains Extra UPDATEs

I’m trying to use OpenJPA to insert some entries in the database and I’m getting a strange number of @UPDATE@s beside the @INSERT@s.

I isolated the problem to the following snippet of code

1
2
3
4
5
6
7
8
9
10
11

1
2
3
4
5
6
7
8
9
10
11
<span class='line'>private void start() {
</span><span class='line'>        EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistencexmltest1PU");
</span><span class='line'>        EntityManager em = emf.createEntityManager();        
</span><span class='line'>        for (int i = 0; i &lt; 10; i++) {
</span><span class='line'>            em.getTransaction().begin();
</span><span class='line'>            MyEntity n =new MyEntity();
</span><span class='line'>            n.setValue(i);
</span><span class='line'>            em.persist(n);        
</span><span class='line'>            em.getTransaction().commit();
</span><span class='line'>        }
</span><span class='line'>    }</span>

The generated SQL looks like this:

INSERT INTO MYTABLE (ID, VALUE, CREATED) VALUES (?, ?, ?) [params=(int) 1, (int) 0, (null) null]
INSERT INTO MYTABLE (ID, VALUE, CREATED) VALUES (?, ?, ?) [params=(int) 2, (int) 1, (null) null]
UPDATE MYTABLE SET CREATED = ? WHERE ID = ? [params=(null) null, (int) 1]
INSERT INTO MYTABLE (ID, VALUE, CREATED) VALUES (?, ?, ?) [params=(int) 3, (int) 2, (null) null]
UPDATE MYTABLE SET CREATED = ? WHERE ID = ? [params=(null) null, (int) 2]
UPDATE MYTABLE SET CREATED = ? WHERE ID = ? [params=(null) null, (int) 1]
INSERT INTO MYTABLE (ID, VALUE, CREATED) VALUES (?, ?, ?) [params=(int) 4, (int) 3, (null) null]
UPDATE MYTABLE SET CREATED = ? WHERE ID = ? [params=(null) null, (int) 3]
UPDATE MYTABLE SET CREATED = ? WHERE ID = ? [params=(null) null, (int) 2]
UPDATE MYTABLE SET CREATED = ? WHERE ID = ? [params=(null) null, (int) 1]
INSERT INTO MYTABLE (ID, VALUE, CREATED) VALUES (?, ?, ?) [params=(int) 5, (int) 4, (null) null]
UPDATE MYTABLE SET CREATED = ? WHERE ID = ? [params=(null) null, (int) 3]
UPDATE MYTABLE SET CREATED = ? WHERE ID = ? [params=(null) null, (int) 4]
UPDATE MYTABLE SET CREATED = ? WHERE ID = ? [params=(null) null, (int) 2]
UPDATE MYTABLE SET CREATED = ? WHERE ID = ? [params=(null) null, (int) 1]
INSERT INTO MYTABLE (ID, VALUE, CREATED) VALUES (?, ?, ?) [params=(int) 6, (int) 5, (null) null]
UPDATE MYTABLE SET CREATED = ? WHERE ID = ? [params=(null) null, (int) 3]
UPDATE MYTABLE SET CREATED = ? WHERE ID = ? [params=(null) null, (int) 4]
UPDATE MYTABLE SET CREATED = ? WHERE ID = ? [params=(null) null, (int) 2]
UPDATE MYTABLE SET CREATED = ? WHERE ID = ? [params=(null) null, (int) 5]
UPDATE MYTABLE SET CREATED = ? WHERE ID = ? [params=(null) null, (int) 1]
...

pay attention to the extra UPDATE statements after each INSERT, the number of extra @UPDATE@s grows as well. From zero @UPDATE@s after the first INSERT, one in the second, two in the third, and so on. I don’t need to say that this is of course really inefficient. I don’t know what is ultimate cause of this but this started when I added a @Temporal(TemporalType.TIMESTAMP) annotation to the entity class. And I can make it go away by calling EntityManager.clear() after each em.getTransaction().commit()

UPDATE: Ok I found a bug report stating that this behaviour is only observed when the entity classes are not enhanced. . So the best solution is use the enhancer. But it really doesn’t work for me, I still get the extra UPDATEs even with enhanced classes. So I’m stuck with the EntityManager.clear() for now.. If the class is PROPERLY ENHANCED the problem goes away.

Check the logs (enable them with <property name="openjpa.Log" value="DefaultLevel=TRACE"/> in persistence.xml) and make sure that you don’t see any entry like

5968  persistencexmltest1PU  INFO   [main] openjpa.Enhance - Creating subclass for "[class com.rubenlaguna.MyEntity]". This means that your application will be less efficient and will consume more memory than it would if you ran the OpenJPA enhancer. Additionally, lazy loading will not be available for one-to-one and many-to-one persistent attributes in types using field access; they will be loaded eagerly instead.

If you see the Creating subclass for message means that the class wasn’t enhanced, as I read OpenJPA really need enhanced classes, un – enhanced are just for testing and trivial examples.+

For reference:

persistence.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<span class='line'>&lt;?xml version="1.0" encoding="UTF-8"?>
</span><span class='line'>&lt;persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
</span><span class='line'>  &lt;persistence-unit name="persistencexmltest1PU" transaction-type="RESOURCE_LOCAL">
</span><span class='line'>    &lt;provider>org.apache.openjpa.persistence.PersistenceProviderImpl&lt;/provider>
</span><span class='line'>    &lt;class>com.rubenlaguna.MyEntity&lt;/class>
</span><span class='line'>    &lt;properties>
</span><span class='line'>      &lt;property name="openjpa.ConnectionPassword" value=""/>
</span><span class='line'>      &lt;property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbc.JDBCDriver"/>
</span><span class='line'>      &lt;property name="openjpa.ConnectionUserName" value="sa"/>
</span><span class='line'>      &lt;property name="openjpa.ConnectionURL" value="jdbc:hsqldb:file:/Users/ecerulm/everjavatest"/>
</span><span class='line'>      &lt;property name="openjpa.Log" value="SQL=TRACE"/>
</span><span class='line'>      &lt;property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(SchemaAction=&apos;add,deleteTableContents&apos;,ForeignKeys=true)"/>
</span><span class='line'>    &lt;/properties>
</span><span class='line'>  &lt;/persistence-unit>
</span><span class='line'>&lt;/persistence></span>

MyEntity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<span class='line'>/*
</span><span class='line'> * To change this template, choose Tools | Templates
</span><span class='line'> * and open the template in the editor.
</span><span class='line'> */
</span><span class='line'>
</span><span class='line'>package com.rubenlaguna;
</span><span class='line'>
</span><span class='line'>import java.util.Date;
</span><span class='line'>import javax.persistence.Column;
</span><span class='line'>import javax.persistence.Entity;
</span><span class='line'>import javax.persistence.GeneratedValue;
</span><span class='line'>import javax.persistence.GenerationType;
</span><span class='line'>import javax.persistence.Id;
</span><span class='line'>import javax.persistence.Table;
</span><span class='line'>import javax.persistence.Temporal;
</span><span class='line'>import javax.persistence.TemporalType;
</span><span class='line'>
</span><span class='line'>/**
</span><span class='line'> *
</span><span class='line'> * @author Ruben Laguna &lt;ruben.laguna at gmail.com>
</span><span class='line'> */
</span><span class='line'>@Entity
</span><span class='line'>@Table(name = "MYTABLE")
</span><span class='line'>public class MyEntity {
</span><span class='line'>    @Id
</span><span class='line'>    @Column(name = "ID")
</span><span class='line'>    @GeneratedValue(strategy=GenerationType.AUTO)
</span><span class='line'>    private Integer id;
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>    @Column(name = "VALUE")
</span><span class='line'>    private Integer attr1;
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>    @Column(name = "CREATED")
</span><span class='line'>    @Temporal(TemporalType.TIMESTAMP)
</span><span class='line'>    private Date created;
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>    public Integer getId() {
</span><span class='line'>        return id;
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>    public void setId(Integer id) {
</span><span class='line'>        this.id = id;
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>    public Integer getValue() {
</span><span class='line'>        return attr1;
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>    public void setValue(Integer value) {
</span><span class='line'>        this.attr1 = value;
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>}</span>

References:

Netbeans Refuses to Recognize persistence.xml (No Visual Editor)

If you create the persistence.xml manually in Windows the file will be created with CRLF line endings (windows style line endings), that will prevent Netbeans for recognizing- Netbeans will not recognize it as the special file it is and won’t be able to to open it with the special/custom visual editor.

netbeans visual editor for persistence files[/caption]

I opened an bug report netbeans issue #172538. At the beginning, I thought the problem was due to different line ending CRLF vs LF issues, but as pointed out in the bug report the line ending has nothing to do with it. It’s just the IDE restart what is needed, no need to change the line endings.

The workaround is easy: change the newline (also line break or end-of-line EOL) characters to Unix style (LF) with any utility. I used Cygwin’s dos2unix (dos2unix src/META-INF/persistence.xml) and then just restart the IDE. Unfortunately just closing and reopening the project containing the persistence.xml file won’t work you have to restart Netbeans.

OpenJPA Enhancer Ant Task in a Netbeans Project

In the build.xml of the project (likely this will be a Java Class Library project), override -post-compile or -pre-jar and invoke <openjpac/>. You will need to add the build/classes and the openjpa jars to <taskdef/> and <openjpac/>. The <openjpac/> will enhance all classes mentioned in persistence.xml (which has to be in the classpath)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<span class='line'>&lt;?xml version="1.0" encoding="UTF-8"?>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>&lt;project name="JpaEntitiesLibrary" default="default" basedir=".">
</span><span class='line'>    &lt;description>Builds, tests, and runs the project JpaEntitiesLibrary.&lt;/description>
</span><span class='line'>    &lt;import file="nbproject/build-impl.xml"/>
</span><span class='line'>    
</span><span class='line'>    &lt;target name="-post-compile">
</span><span class='line'>        &lt;echo message="begin openJPAC"/>
</span><span class='line'>        &lt;path id="openjpa.path.id">        
</span><span class='line'>            &lt;pathelement location="${build.classes.dir}"/>
</span><span class='line'>
</span><span class='line'>             &lt;!-- Adding the OpenJPA jars into the classpath -->
</span><span class='line'>            &lt;fileset dir="C:\Users\ecerulm\Downloads\apache-openjpa-1.2.1-binary\apache-openjpa-1.2.1\lib" includes="*.jar"/>
</span><span class='line'>             &lt;!--  or if you create a OpenJPA Library you can use that instead  -->
</span><span class='line'>            &lt;!--&lt;pathelement path="${libs.OpenJPA.classpath}"/>-->
</span><span class='line'>        &lt;/path>
</span><span class='line'>
</span><span class='line'>        &lt;taskdef name="openjpac" classname="org.apache.openjpa.ant.PCEnhancerTask">
</span><span class='line'>            &lt;classpath refid="openjpa.path.id"/>
</span><span class='line'>        &lt;/taskdef>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>        &lt;openjpac>            
</span><span class='line'>            &lt;classpath refid="openjpa.path.id"/>
</span><span class='line'>        &lt;/openjpac>
</span><span class='line'>        &lt;echo message="end openJPAC"/>
</span><span class='line'>    &lt;/target>
</span><span class='line'>    
</span><span class='line'>&lt;/project></span>

You can refer to the OpenJPA jars by either a <fileset> with the file path to the OpenJPA directory or by refererring to a Netbeans Library instead. You can create a OpenJPA Library via Tools ⇒ Libraries ⇒ New Library and add all the jars to the Library. If you name the library “OpenJPA” then you can refer to its classpath with <pathelement path="${libs.OpenJPA.classpath}"/>. See the commented code in the build.xml above.

IMPORTANT+: You may be tempted to put the <path> and the <taskdef> outside the <target>. I strongly disencorage this. If you do so then you need to ensure that ./build/classes directory is there before <path> is evaluated otherwise openjpac will fail to locate the META-INF/persistence.xml. So when you do an ant clean, the build/classes is deleted. If you do a ant jar after the ant clean, the build/classes will not be picked up by path and it will fail with a

 [openjpac] <openjpa-1.2.1-r752877:753278 fatal user error> org.apache.openjpa.u
til.MetaDataException: MetaDataFactory could not be configured (conf.newMetaData
FactoryInstance() returned null). This might mean that no configuration properti
es were found. Ensure that you have a META-INF/persistence.xml file, that it is
available in your classpath, or that the properties file you are using for confi
guration is available. If you are using Ant, please see the <properties> or <pro
pertiesFile> attributes of the task's nested <config> element. This can also occ
ur if your OpenJPA distribution jars are corrupt, or if your security policy is
overly strict.
 [openjpac]     at org.apache.openjpa.meta.MetaDataRepository.initializeMetaData
Factory(MetaDataRepository.java:1567)

Although you can ensure that build/classes is always there overriding -post-clean and creating it there with something like:

1
2
3

1
2
3
<span class='line'>&lt;target name="-post-clean">
</span><span class='line'>        &lt;mkdir dir="${build.classes.dir}"/>
</span><span class='line'>&lt;/target></span>

Then you will fall into a second problem: ${build.classes.dir} variable is not accesible outside the <target>. That variable is loaded through -init-project target. So you will be forced to use something like ./build/classes instead of a proper ${build.classes.dir}. So it’s better to define the task inside the target.

By the way, if you don’t set properly the classpath you will probably get an exception like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<span class='line'>java.lang.IllegalArgumentException: java.lang.ClassNotFoundException: com.rubenlaguna.jpaentities.Notes
</span><span class='line'>        at serp.util.Strings.toClass(Strings.java:164)
</span><span class='line'>        at serp.util.Strings.toClass(Strings.java:108)
</span><span class='line'>        at serp.bytecode.BCClass.getType(BCClass.java:566)
</span><span class='line'>        at org.apache.openjpa.enhance.PCEnhancer.&lt;init>(PCEnhancer.java:249)
</span><span class='line'>        at org.apache.openjpa.enhance.PCEnhancer.run(PCEnhancer.java:4493)
</span><span class='line'>        at org.apache.openjpa.ant.PCEnhancerTask.executeOn(PCEnhancerTask.java:89)
</span><span class='line'>        at org.apache.openjpa.lib.ant.AbstractTask.execute(AbstractTask.java:172)
</span><span class='line'>        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
</span><span class='line'>        at sun.reflect.GeneratedMethodAccessor75.invoke(Unknown Source)
</span><span class='line'>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
</span><span class='line'>        at java.lang.reflect.Method.invoke(Method.java:597)
</span><span class='line'>        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
</span><span class='line'>        at org.apache.tools.ant.Task.perform(Task.java:348)
</span><span class='line'>        at org.apache.tools.ant.Target.execute(Target.java:357)
</span><span class='line'>        at org.apache.tools.ant.Target.performTasks(Target.java:385)
</span><span class='line'>        at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1337)
</span><span class='line'>        at org.apache.tools.ant.Project.executeTarget(Project.java:1306)
</span><span class='line'>        at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
</span><span class='line'>        at org.apache.tools.ant.Project.executeTargets(Project.java:1189)
</span><span class='line'>        at org.apache.tools.ant.module.bridge.impl.BridgeImpl.run(BridgeImpl.java:278)
</span><span class='line'>        at org.apache.tools.ant.module.run.TargetExecutor.run(TargetExecutor.java:497)
</span><span class='line'>        at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:151)
</span><span class='line'>java.lang.IllegalArgumentException: java.lang.ClassNotFoundException: com.rubenlaguna.jpaentities.Notes
</span><span class='line'>        at serp.util.Strings.toClass(Strings.java:164)
</span><span class='line'>        at serp.util.Strings.toClass(Strings.java:108)
</span><span class='line'>        at serp.bytecode.BCClass.getType(BCClass.java:566)
</span><span class='line'>        at org.apache.openjpa.enhance.PCEnhancer.&lt;init>(PCEnhancer.java:249)
</span><span class='line'>        at org.apache.openjpa.enhance.PCEnhancer.run(PCEnhancer.java:4493)
</span><span class='line'>        at org.apache.openjpa.ant.PCEnhancerTask.executeOn(PCEnhancerTask.java:89)
</span><span class='line'>        at org.apache.openjpa.lib.ant.AbstractTask.execute(AbstractTask.java:172)
</span><span class='line'>        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
</span><span class='line'>        at sun.reflect.GeneratedMethodAccessor75.invoke(Unknown Source)
</span><span class='line'>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
</span><span class='line'>        at java.lang.reflect.Method.invoke(Method.java:597)
</span><span class='line'>        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
</span><span class='line'>        at org.apache.tools.ant.Task.perform(Task.java:348)
</span><span class='line'>        at org.apache.tools.ant.Target.execute(Target.java:357)
</span><span class='line'>        at org.apache.tools.ant.Target.performTasks(Target.java:385)
</span><span class='line'>        at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1337)
</span><span class='line'>        at org.apache.tools.ant.Project.executeTarget(Project.java:1306)
</span><span class='line'>        at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
</span><span class='line'>        at org.apache.tools.ant.Project.executeTargets(Project.java:1189)
</span><span class='line'>        at org.apache.tools.ant.module.bridge.impl.BridgeImpl.run(BridgeImpl.java:278)
</span><span class='line'>        at org.apache.tools.ant.module.run.TargetExecutor.run(TargetExecutor.java:497)
</span><span class='line'>        at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:151)</span>

References:

Adding a Google Search Web Element to a Wordpress Theme

The newly released Google Web element: custom search is awesome.

csewebelement

To add it to my wordpress theme (which doesn’t have a top sidebar for widgets) I had to edit (Appearance ⇒ Editor) the header.php file and add the snippet I got from Google there, at just at the end of the header.php. So the search web element is show right after the banner and before the posts.

In my case the code is

. 
<!-- Google search web element BEGIN-->
<div id="cse" style="width:100%;">Loading</div>
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
  google.load('search', '1');
  google.setOnLoadCallback(function(){
    new google.search.CustomSearchControl('partner-pub-6449419902780618:ybxd02gp4hx').draw('cse');
  }, true);
</script>
<!-- Google search web element END-->

Also available as gist

If your theme has a top sidebar for widgets you can add the snippet as a text widgets instead there (to avoid fiddling editing the theme).

STaX: OutOfMemoryError When Parsing Big Files

Java 6 includes STaX , when I tried to parse a Evernote backup file with it, I got a OOME error.

1
2
3
4
5
6
7
8
9
10

1
2
3
4
5
6
7
8
9
10
<span class='line'>java.lang.OutOfMemoryError: Java heap space
</span><span class='line'>     at com.sun.org.apache.xerces.internal.util.XMLStringBuffer.append(XMLStringBuffer.java:205)
</span><span class='line'>     at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.refresh(XMLDocumentScannerImpl.java:1520)
</span><span class='line'>     at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.invokeListeners(XMLEntityScanner.java:2070)
</span><span class='line'>     at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.peekChar(XMLEntityScanner.java:486)
</span><span class='line'>     at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2679)
</span><span class='line'>     at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
</span><span class='line'>     at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
</span><span class='line'>     at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:548)
</span><span class='line'>     at</span>

Googling a bit I found a bug report 6536111. It says that this should be fixed in 1.6.0_14. But I tried Sun 1.6.0_16 and no luck. I got the exact same thing.

By the way I get this error in both Windows Vista and Mac OS X 10.5.6.

So I decided to go and use WoodStox instead (which is also a STaX API implementation). I worked like a charm.

At the beginning I though I would need to put the woodstox jars in the endorsed dir (-Djava.endorsed.dirs=“xxx”) but actually it’s not necessary at all.

You just put the woodstox’s jars (stax2-api-3.0.1.jar,woodstox-core-lgpl-4.0.5.jar) in the classpath and that’s it. In my case I was using it in a Netbeans Platform Application (RCP) so I created a Netbeans Library Wrapper with the two jars in it and make my module depend on this new library wrapper.

1
2
3
4
5
6
7
8
9

1
2
3
4
5
6
7
8
9
<span class='line'>&lt;class-path-extension>
</span><span class='line'>                &lt;runtime-relative-path>ext/woodstox-core-lgpl-4.0.5.jar&lt;/runtime-relative-path>
</span><span class='line'>                &lt;binary-origin>release/modules/ext/woodstox-core-lgpl-4.0.5.jar&lt;/binary-origin>
</span><span class='line'>            &lt;/class-path-extension>
</span><span class='line'>            
</span><span class='line'>            &lt;class-path-extension>
</span><span class='line'>                &lt;runtime-relative-path>ext/stax2-api-3.0.1.jar&lt;/runtime-relative-path>
</span><span class='line'>                &lt;binary-origin>release/modules/ext/stax2-api-3.0.1.jar&lt;/binary-origin>
</span><span class='line'>            &lt;/class-path-extension></span>

The JARs use the Service Provider (SPI) feature of jar files to register themselves as an STaX implementation. No changes in the code, you still use the STaX interface to do the parsing but the WoodStox implementation will be used instead.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<span class='line'>...
</span><span class='line'>...
</span><span class='line'>                in = new FileInputStream(toAdd);
</span><span class='line'>                XMLInputFactory factory = XMLInputFactory.newInstance();
</span><span class='line'>                factory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
</span><span class='line'>                XMLStreamReader parser = factory.createXMLStreamReader(in);
</span><span class='line'>                int inHeader=0;
</span><span class='line'>                for (int event = parser.next();
</span><span class='line'>                        event != XMLStreamConstants.END_DOCUMENT;
</span><span class='line'>                        event = parser.next()) {
</span><span class='line'>                    switch (event) {
</span><span class='line'>                        case XMLStreamConstants.START_ELEMENT:
</span><span class='line'>                            if ("title".equals(parser.getLocalName())) {
</span><span class='line'>                                inHeader++;
</span><span class='line'>                            }
</span><span class='line'>                            ....
</span><span class='line'>                            ....
</span><span class='line'>                            ....</span>

JTable, Beans Binding and JPA Pagination

In my previous post I talk about JTable and JPA pagination through a custom TableModel.

Now working directly with TableModel is not want you want to do, you want to use Beans Bindings because it means less manual coding and a lot of help from the IDE (like Netbeans).

With netbeans you can easily bind a JTable to the result list of JPA query. But if that Query returns thousands of rows it’s going to be slow or unfeasible. And if you try to use JPA pagination (with Query.setMaxResults()) then you end with a table that will only show a subset of the rows.

By the way, choose wisely your JPA Provider/DB Provider combination, as some combinations will not give you any real paginations at all. For example, neither OpenJPA, Hibernate or TopLink/EclipseLink seems to support Apache Derby pagination (OFFSET/FETCH). The example here uses Derby and TopLink which is a bad example because the JPA pagination doesn’t get translated to SQL command for pagination. So if you really want proper pagination you should use other combination like Hibernate JPA/HSQLDB.

The “trick” here is to avoid binding the Table to the the result list given by the Query.getResultList(). You can create a custom List that does the JPA pagination behind the curtains and bind the JTable to that List instead.

How is this different from doing a custom TableModel? custom TableModel, custom List sound like the same amount of work. Well, right is the same amount of work but if you use Beans Bindings you get a lot of help from the IDE to manipulate the JTable graphically, etc.

You can follow any of the existing tutorials to create JTables bound to JPA entities to get an idea of how Beans Binding work.

Now I’m going to modify the test aplication from my previous post to use Beans Bindings together with the JPA pagination.

I’m assuming that the Entity class Customers from the previous post is already there, and TopLink and derby jars are in the classpath.

Here are the steps to create a JTable bound via Beans Binding to a List backed by a JPA Query:

Right-click on the project New ⇒ JFrame Form

JFrame Form wizard

Add the Table from the Palette to the JFrame

Adding a Table to the frame

Now we can add the EntityManager and the Query. Instead of adding those manually by typing we can add them graphically. Right-click on the Other Components item on the Inspector Window and selecting Add from Palette ⇒ Java Persistence ⇒ Entity Manager

inspector window

Now we can configure the EntityManager by selecting it in the Inspector window and changing the properties in the Properties windows.
entitymanager properties

In this case we change the persistenceUnit to “JTablePaginationJPAPU” .

Then we can add the Query to the form. Inspector ⇒ Other Components ⇒ Add from Palette ⇒ Java Persistence ⇒ Query

And then we configure the query by changing its name to getRowsQuery and changing the query property to “SELECT c FROM Customers c” and the entityManager to “entityManager1”:

query properties

Add a second query to the form to get the number of rows in the table. Call it getRowCount and set the entityManager to “entityManager1” and the query to “SELECT COUNT(c) FROM Customer c

inspector2

getRowCount

Now we need a Query List because that is what we will bind to the JTable. Again Inspector ⇒ Other Components ⇒ Add to Palette ⇒ Java Persistence ⇒ Query Result.

We could link the Query Result to the Query but we won’t do that because then we don’t get pagination. What we will do with the query result is to change the “Custom Creation Code” property to “getList()” a method call that we will implement later. We also change the “Type Parameters” property to <Customers> to let the IDE know the type of objects stored in the list so netbeans is able to make suggestions later when we bind the JTable to this list.

query result properties

Now we add the getList() method to our class

1
2
3
4

1
2
3
4
<span class='line'>private List&lt;Customers> getList() {
</span><span class='line'>        List&lt;Customers> toReturn = new ResultListJPA&lt;Customers>(rowCountQuery, getRowsQuery);
</span><span class='line'>        return toReturn;
</span><span class='line'>    }</span>

You can create ResultListJPA class in the same file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<span class='line'>class ResultListJPA&lt;T> extends AbstractList&lt;T> implements List&lt;T> {
</span><span class='line'>
</span><span class='line'>    private final Query rowCountQuery;
</span><span class='line'>    private final Query getRowsQuery;
</span><span class='line'>    private int startPosition;
</span><span class='line'>    private int counter=0;
</span><span class='line'>    private List&lt;T> cache = null;
</span><span class='line'>
</span><span class='line'>    ResultListJPA(Query rowCountQuery, Query getRowsQuery) {
</span><span class='line'>        this.rowCountQuery = rowCountQuery;
</span><span class='line'>        this.getRowsQuery = getRowsQuery;
</span><span class='line'>        this.startPosition = 0;
</span><span class='line'>        this.cache = getItems(startPosition, startPosition + 100);
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>    public int size() {
</span><span class='line'>        return ((Long) rowCountQuery.getSingleResult()).intValue();
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>    public T get(int rowIndex) {
</span><span class='line'>        if ((rowIndex >= startPosition) && (rowIndex &lt; (startPosition + 100))) {
</span><span class='line'>        } else {
</span><span class='line'>            this.cache = getItems(rowIndex, rowIndex + 100);
</span><span class='line'>            this.startPosition = rowIndex;
</span><span class='line'>        }
</span><span class='line'>        T c = cache.get(rowIndex - startPosition);
</span><span class='line'>
</span><span class='line'>        return c;
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>    private List&lt;T> getItems(int from, int to) {
</span><span class='line'>        System.out.println("numer of requests to the database " + counter++);
</span><span class='line'>        Query query = getRowsQuery.setMaxResults(to - from).setFirstResult(from);
</span><span class='line'>
</span><span class='line'>        //add the cache
</span><span class='line'>        List&lt;T> resultList = query.getResultList();
</span><span class='line'>        return resultList;
</span><span class='line'>    }
</span><span class='line'>}</span>

OK, now we’ll bind the result list object with the JTable. Right-click on the JTable and select Table Contents ⇒ Bound ⇒ Binding Source ⇒ list1 . list1 is the name of the ResultListJPA object in my case.
table binding

Now click on the Columns tab and Insert 3 new columns. Select the first one and change the Title to “Id Number” and select “id” in the expression combo box (it should appear as ${id}).

Do the same thing for the other 2 columns until you get something like this
Table binding

Now the JTable is properly bound to the list and we can run the file. You can see in the screenshot that the JTable shows the contents of the database and it makes new queries to the database as you scroll through the JTable.

final

The source code is here

References

JTable and JPA Pagination Through Custom TableModel

I really want to talk about JTable, Beans Binding and JPA pagination but I think I need to write about JTable and JPA pagination first. So I will take the Beans binding stuff in another post.

By the way, choose wisely your JPA Provider/DB Provider combination, as some combinations will not give you any real paginations at all. For example, neither OpenJPA, Hibernate or TopLink/EclipseLink seems to support Apache Derby pagination (OFFSET/FETCH). The example here uses Derby and TopLink which is a bad example because the JPA pagination doesn’t get translated to SQL command for pagination. So if you really want proper pagination you should use other combination like Hibernate JPA/HSQLDB.

To get a JTable showing data from a paginated JPA Query you need to create a Custom TableModel for the JTable like this one:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<span class='line'>class JPAPaginationTableModel extends AbstractTableModel {
</span><span class='line'>
</span><span class='line'>    private final EntityManager manager;
</span><span class='line'>    private  int startPosition;
</span><span class='line'>    private  List&lt;Customers> theList;
</span><span class='line'>    private int counter=0;
</span><span class='line'>
</span><span class='line'>    JPAPaginationTableModel(EntityManager manager) {
</span><span class='line'>        this.manager = manager;
</span><span class='line'>        this.startPosition = 0;
</span><span class='line'>        this.theList = getItems(startPosition, startPosition+100);
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>    public int getRowCount() {
</span><span class='line'>        return ((Long) manager.createQuery("SELECT COUNT(c) FROM Customers c").getSingleResult()).intValue();
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>    public int getColumnCount() {
</span><span class='line'>        return 3;
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>    public Object getValueAt(int rowIndex, int columnIndex) {
</span><span class='line'>
</span><span class='line'>        if((rowIndex >= startPosition) && (rowIndex&lt;(startPosition+100))){
</span><span class='line'>
</span><span class='line'>        } else
</span><span class='line'>        {
</span><span class='line'>            this.theList = getItems(rowIndex, rowIndex+100);
</span><span class='line'>            this.startPosition=rowIndex;
</span><span class='line'>        }
</span><span class='line'>        Customers c = theList.get(rowIndex-startPosition);
</span><span class='line'>
</span><span class='line'>        Object toReturn = null;
</span><span class='line'>        switch (columnIndex) {
</span><span class='line'>            case 0:
</span><span class='line'>                toReturn = c.getId();
</span><span class='line'>                break;
</span><span class='line'>            case 1:
</span><span class='line'>                toReturn = c.getFirstName();
</span><span class='line'>                break;
</span><span class='line'>            case 2:
</span><span class='line'>                toReturn = c.getLastName();
</span><span class='line'>                break;
</span><span class='line'>            default:
</span><span class='line'>                toReturn = c.getId();
</span><span class='line'>
</span><span class='line'>        }
</span><span class='line'>        return toReturn;
</span><span class='line'>    }
</span><span class='line'>    private List&lt;Customers> getItems(int from, int to) {
</span><span class='line'>        System.out.println("number of requests to the database "+counter++);
</span><span class='line'>        Query query = manager.createQuery("SELECT c FROM Customers c").setMaxResults(to-from).setFirstResult(from);
</span><span class='line'>
</span><span class='line'>        //add the cache
</span><span class='line'>        List&lt;Customers> resultList = query.getResultList();
</span><span class='line'>        return resultList;
</span><span class='line'>    }
</span><span class='line'>}</span>

The getValueAt in this custom TableModel make use from a paginated (setMaxResults) JPA query that take 100 rows each time. The database contains 30000 rows but with this TableModel you won’t need to retrieve all of them to display the JTable. Only the rows that need to be shown will be retrieved.

To fully understand this custom TableModel I think it’s better to illustrate a full application so I’m going how to describe how to create an example application with netbeans:


  1. First we need a database, I used Java DB. Go to Netbeans ⇒ Services. Right click on Java DB and select Start server.

  2. p.

  3. Create a database. database name “namesdb” username and password “nbuser”.
  4. Connect to the newly created database
  5. Execute command
  6. download the following sql script to create a table and insert 30000 rows. And execute it in sql command window
  7. Now we have a table with 30000 entries that we want to show in a JTable
  8. Let’s create a project in netbeans. New project ⇒ Java ⇒ Java Application
  9. new project

  10. Let’s create the JPA Entity class for the database. Select the project and click on New ⇒
  11. create entity classes for database

  12. In the wizard select the connection and the customers table
  13. entity classes wizard

  14. Create a Persistence Unit also and specify TopLink as provider
  15. create persistence unit

  16. Now you have created the entity classes for Customers
  17. Now we need to add the Java DB / Derby drivers to the project so TopLink is able to find the drive to connect to the database. Right-click on the project Properties ⇒ Libraries ⇒ Add Library and select or create a library for derby
  18. add derby library

    derby library

  19. Now we can create our GUI
  20. New ⇒ JPanel Form. Type JTablePaginationExample as class name
  21. jpanel form

  22. Drop a JTable into the form from the Palette

  23. Adding JTable
  24. Now let’s add a custom TableModel to this JTable. Switch to the Source view and add the following
  25. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <span class='line'>private TableModel getTableModel() {
    </span><span class='line'>        EntityManager manager = Persistence.createEntityManagerFactory("JTablePaginationJPAPU").createEntityManager();
    </span><span class='line'>
    </span><span class='line'>        return new JPAPaginationTableModel(manager);
    </span><span class='line'>    }
    </span><span class='line'>
    </span><span class='line'>   public static void main(String args[]) {
    </span><span class='line'>        java.awt.EventQueue.invokeLater(new Runnable() {
    </span><span class='line'>
    </span><span class='line'>            public void run() {
    </span><span class='line'>                JFrame frame = new JFrame("JTable with custom TableModel and JPA");
    </span><span class='line'>                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    </span><span class='line'>                JComponent panel = new JTablePaginationExample();
    </span><span class='line'>                frame.add(panel);
    </span><span class='line'>                frame.pack();
    </span><span class='line'>                frame.setVisible(true);
    </span><span class='line'>            }
    </span><span class='line'>        });
    </span><span class='line'>    }</span>

    and at the end of the file add a new class

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    <span class='line'>class JPAPaginationTableModel extends AbstractTableModel {
    </span><span class='line'>
    </span><span class='line'>    private final EntityManager manager;
    </span><span class='line'>    private int startPosition;
    </span><span class='line'>    private List&lt;Customers> theList;
    </span><span class='line'>    private int counter = 0;
    </span><span class='line'>
    </span><span class='line'>    JPAPaginationTableModel(EntityManager manager) {
    </span><span class='line'>        this.manager = manager;
    </span><span class='line'>        this.startPosition = 0;
    </span><span class='line'>        this.theList = getItems(startPosition, startPosition + 100);
    </span><span class='line'>    }
    </span><span class='line'>
    </span><span class='line'>    public int getRowCount() {
    </span><span class='line'>        return ((Long) manager.createQuery("SELECT COUNT(c) FROM Customers c").getSingleResult()).intValue();
    </span><span class='line'>    }
    </span><span class='line'>
    </span><span class='line'>    public int getColumnCount() {
    </span><span class='line'>        return 3;
    </span><span class='line'>    }
    </span><span class='line'>
    </span><span class='line'>    public Object getValueAt(int rowIndex, int columnIndex) {
    </span><span class='line'>
    </span><span class='line'>        if ((rowIndex >= startPosition) && (rowIndex &lt; (startPosition + 100))) {
    </span><span class='line'>        } else {
    </span><span class='line'>            this.theList = getItems(rowIndex, rowIndex + 100);
    </span><span class='line'>            this.startPosition = rowIndex;
    </span><span class='line'>        }
    </span><span class='line'>        Customers c = theList.get(rowIndex - startPosition);
    </span><span class='line'>
    </span><span class='line'>        Object toReturn = null;
    </span><span class='line'>        switch (columnIndex) {
    </span><span class='line'>            case 0:
    </span><span class='line'>                toReturn = c.getId();
    </span><span class='line'>                break;
    </span><span class='line'>            case 1:
    </span><span class='line'>                toReturn = c.getFirstName();
    </span><span class='line'>                break;
    </span><span class='line'>            case 2:
    </span><span class='line'>                toReturn = c.getLastName();
    </span><span class='line'>                break;
    </span><span class='line'>            default:
    </span><span class='line'>                toReturn = c.getId();
    </span><span class='line'>
    </span><span class='line'>        }
    </span><span class='line'>        return toReturn;
    </span><span class='line'>    }
    </span><span class='line'>
    </span><span class='line'>    private List&lt;Customers> getItems(int from, int to) {
    </span><span class='line'>        System.out.println("numer of requests to the database " + counter++);
    </span><span class='line'>        Query query = manager.createQuery("SELECT c FROM Customers c").setMaxResults(to - from).setFirstResult(from);
    </span><span class='line'>
    </span><span class='line'>        //add the cache
    </span><span class='line'>        List&lt;Customers> resultList = query.getResultList();
    </span><span class='line'>        return resultList;
    </span><span class='line'>    }
    </span><span class='line'>}</span>

  26. Now you can run it. Select JTablePaginationExample and “Run File”
  27. JTablePaginationExample

  28. You can download the full source code of JTablePaginationExample.java
  29. Links

    Copyright © 2015 - Ruben Laguna - Powered by Octopress