Blog Archives

March 5th, 2011
7:16 pm
JPA entities – field vs method annotation

Posted under JPA
Tags , , ,

Having read a number of technical blogs on this there appeared to be no clear winner either way, until I hit a requirement to use a mapped superclass for an entity. Then the following issues became very important:-

  1. Annotating fields gives you less flexibility – methods can be overriden by a subclass, whereas fields cannot.
  2. My particular example where I hit this was when designing an implementation to use for hierarchical/tree structured data, to be used in a number of places in an application. I wanted to make all the tree usage polymorphic from the same base class implementation, as then various other areas of the code could be reused for any tree. As entities were passed all the way up to the (JSF) UI, I was using certain design patterns for handling hierarchies at the UI level and making them able to handle any tree was desirable.
  3. Some of the functionality for handling trees – in my case path enumerated trees as described here in this excellent article on slideshare.net – could be placed in a base class. Examples of this were methods to compress node Ids in the path enumerated string using Base64, and building tree path strings for use at the UI etc.
  4. A key gotcha was that I wanted different impementations of trees to be annotated differently, for example to use different sequence Id generation. If the tree Id was in the mapped superclass and I was using field annotation, I was stuck. This issue is discussed in these articles here (see the comments at the end) and here.

My solution was to take the decision to always annotate (getter) methods from now on. This allowed the following implementation:-

  1. My mapped superclass contained getters annotated @Transient where I wanted to change their behaviour in a subclass. For example, my treeId primary key was in the superclass but marked @Transient so that it would not be mapped there. Then, in each subclass, I added an override getter/setter pair for the field, and annotated the getter with the desired ID generation. This allowed every subclass to have its own sequence generation (in my case), but to still allow polymorphic usage in other code.
  2. When doing this, a classic gotcha was to forget to mark the base class getters @Transient. This caused them to be mapped in both the mapped superclass and the subclass, resulting in multiple writable mappings which Eclipselink complained about loudly! It feels counter-intuitive to set them as transient, but the important point is that they will be mapped by the subclass.
  3. When doing this, I had to explicitly annotate the mapped superclass for property annotation using @Access(AccessType.PROPERTY). This is because normally the default type of access (field or property) is derived automatically from where the primary key is annotated. In this case, there was no such annotation on the mapped superclass so it needed telling – again, strange and loud Eclipselink errors resulted without this as my @Transient annotations on getters in the superclass were being ignored, as it defaulted to field annotation!
  4. Another issue was that I wanted a name field in the base superclass, but wanted to override this in the subclasses. In fact one tree implementation had node classes with an associated keyword class, where the name was stored on the keyword class and delegated from the getter on the node class, which in turn overrode the getter in the mapped superclass. Again, I marked the name getters as @Transient in both the tree mapped superclass and in the node class, and just mapped the name in the keyword class. This allowed other code to obtain the name polymorphically using a base superclass reference, but the actual name came from 2 levels further down. JPA was kept happy as the name was mapped wherever I needed it to be.

The following sample code fragment from my mapped superclass illustrated some of these points:-

package uk.co.salientsoft.test.domain;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;

import uk.co.salientsoft.jpa.ColumnMeta;

/**
* Entity implementation class for Entity: TreeNode
* This mapped superclass performs the common tree/treepath handling for all tree entities
*
*/
@MappedSuperclass
@Access(AccessType.PROPERTY)
public abstract class TreeNode {
   
    private long TreeNodeId;
    private String treePath;
    private int nodeLevel;

    @Transient public long getTreeNodeId() {return this.TreeNodeId;}
    @Transient public void setTreeNodeId(long TreeNodeId) {this.TreeNodeId = TreeNodeId;}
   
    @Transient public abstract String getName();
    @Transient public abstract void setName(String name);

No Comments »

March 4th, 2011
5:48 pm
Breadcrumb Composite Component using ui:repeat

Posted under JSF
Tags , , , , , , ,

Update 16/1/2012

A bug was found in the crumb styling. max-width was correctly set on the crumbs to truncate them, but when white space is present in a crumb, the default is to wrap at the max-width. This causes the breadcrumb to increase in height and add a second line. The fix was to turn off the wrapping by setting “white-space:nowrap” in the css for the crumb anchor tags (see Mantis issue 99 for details) :-

.ss-breadcrumb ul li,
.ss-breadcrumb ul li a {
    overflow:hidden!important;
    display:inline-block;
    white-space:nowrap;
    text-decoration: none;
}

 

Original Post

This follows on from my previous posts on the Primefaces breadcrumb here  and here.

I found a couple of further important issues I hit when using the standard breadcrumb:-

  1. In order to add and remove crumbs dynamically, it uses the Primefaces MenuModel. Methods of the MenuItem class are used to add actions and listeners.
  2. The mechanism seems somewhat cumbersome. In particular, it does not appear to be easy to pass a particular target object as an argument to an action or listener method, as the binding appears to be created as a string. Ideally what I would want is for the breadcrumb entries to be created by iterating a list using a var attribute like a table, and then to pass the var object containing the current crumb in the list as an argument in a method call to an action when that crumb was clicked.
  3. The only way I could see to do it involved passing an identifier for an object (such as the primary key for an entity). Whilst I certainly did not bottom it out completely, the mechanism seemed somewhat complex to use and lacking in flexibility.

Adding these issues to the ones already highlighted in the other posts (in particular the slowness of the jQuery operations when initially collapsing a breadcrumb in preview mode), I decided to take the step of rolling my own custom breadcrumb. The following approach was taken:-

  1. I decided to use a composite component rather than create a full blown custom component in code, as this looked more straightforward, and I had experience of composite component creation.
  2. The key factor which made this possible was that I could use ui:repeat to build the breadcrumbs dynamically from a list.
  3. Conditionally rendered xhtml tags could be handled using ui:fragment within the ui:repeat loop. This allowed the use of the rendered attribute on ui:fragment to optionally render sections even when standard non-jsf html tags such as <li> were used. For example, the root crumb of the component is rendered differently to the others, using an icon only. Also, full width crumbs are rendered differently to truncated crumbs (when truncating the component to fit a target width)

The following are the key features and design points for the breadcrumb:-

  1. The component is designed specifically for dynamic use, being driven from a list much like a table. It is not possible to build it statically on the facelets page (static use is covered by the standard control so this was specifically a non-goal/non-requirement).
  2. It is rendered entirely statically, so there is no (potentially slow) javascript/jQuery stuff going on at render time or during use.
  3. Compression to fit a target width is done by passing the desired target width in to the control. This is then used to set max-width css properties on the crumbs. This allows the crumbs to take the width they need and to only be truncated when they hit the max value. The max value is calculated on the server at render time by dividing the max target width by the number of crumbs to be rendered (allowing for the root crumb as a special case).
  4. The full text for a crumb can be viewed at any time by hovering over the crumb – it is displayed using the HTML title attribute. This is one annoyance with the standard Primefaces control – it does not allow use of the title attribute. Using the title  attribute allows the control to be static on the page for speed but still allows truncated crumbs to be easily read.
  5. The component supports the concept of stale crumbs. The idea is that when moving back up the crumb path (leftwards, or navigating up a tree path), the crumbs to the right which were previously visited are not immediately removed. They are highlighted differently as non bold and italic to make them less important compared to the ‘fresh’ crumbs on the path. In addition, the current crumb is underlined in order to make it completely clear where the current position is. Without stale crumbs present, this would normally be the rightmost crumb, but this will now no longer be the case if stale crumbs are present.
  6. Stale crumbs are only removed if the user navigates down a different tree path which invalidates them, in which case they disappear. Provided the user remains on the same tree path, the crumbs will be left in place.
  7. The stale crumbs may be clicked for navigation just like the fresh ones, to allow the user to revisit old ‘stale’ locations. When a stale crumb is revisited, it changes back to a fresh crumb again (as do all other stale crumbs to its left) and it becomes the current crumb – it is therefore rendered in bold, non-italic, and is underlined. The crumbs to the right of it if any still remain stale as they were before.
  8. To assist navigation up a tree structured hierarchy, it is common to include an ‘up’ button somewhere. This is taken a step further by including both up (= left pointing) and down (=right pointing)buttons on the left hand side of the breadcrumb component. When combined with stale crumb support, this feature allows easy navigation both up and down a given tree path. The right button is only enabled when stale crumbs are present, and clicking it moves down the stale crumb list just as if the next stale crumb was clicked. Navigating to the root of the tree (leftmost crumb) disables the left button.
  9. The component is styled in a similar way to the standard Primefaces component, and uses the same CSS classes for the styling.
  10. Styling may be modified, and features such as up/down support turned on or off.
  11. The component is styled using an inner div which holds the component itself – this can be floating if desired in which case it resizes the width to hold its contents. The inner div is contained in an outer div which is typically fixed in size to suit the page, allowing the inner div to scale up to that size. The width used for crumb truncation calculation is passed separately into the control – this will normally be slightly less than the max width set for the divs.
  12. The component is backed by a controller backing bean, BreadcrumbCtrl/BreadcrumbCtrlImpl, which may be subclassed to allow further customisation. The crumbs are passed into the bean as a simple generic list, and a property name used for the crumb text display is passed as a string attribute to the composite component. The controller fields action and listener events from the component, and passes them on using a BreadcrumbEvent interface – an object implementing this interface is passed into the controller bean at init time. When the user clicks on a crumb, the actual crumb in the list plus its list index are simply passed to its action method. When multiple components are used on a page, each will have their own controller object. These will typically be injected into the page backing bean e.g. by CDI as dependent beans. When the action and listener events are called, the actual controller object is also passed. This would allow for example the page backing bean to implement BreadcrumbEvent and manage actions for a number of dependent breadcrumb controllers, using the passed controller object to determine which one was clicked.

The following are some of the key technical issues which arose during development of the component:-

  • ui:repeat is used for iterative xhtml generation of the crumbs. This uses a var attribute like a table to represent the current object (crumb) in the list. It also supports a varstatus attribute which allows access to various loop properties within the loop, such as the current loop index, first and last boolean properties and others. The index property in particular is used to determine styling for the current crumb and stale crumbs etc.
  • In addition, the varstatus object (com.sun.faces.facelets.tag.jstl.core.IterationStatus) can be accessed from the controller bean using code similar to the following, where varStatusKey is the name given in the varstatus attribute to ui:repeat:-

Map<String, Object> requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
IterationStatus varStatus = IterationStatus) requestMap.get(varStatusKey);

  • It is important to note that whilst it is tempting to cache the varstatus object in the controller bean, this does not work – a new object must be obtained each time using the above code.
  • ui:fragment can be used directly in the ui:repeat loop within the composite component implementation – it is not immediately obvious from the documentation that this is the case.
  • When declaring the attributes for the composite component using <composite:attribute>, note that the type attribute allows specification of a particular object type, the required attribute makes an attribute mandatory, and the default attribute sets a default.

The source code and a usage example of the breadcrumb control may be found in the repository here.

No Comments »

February 11th, 2011
5:49 pm
Further h:outputStylesheet issues

Posted under JSF
Tags , , , , , , ,

I needed to load a custom style sheet for a composite component.

Primefaces has problems loading theme images correctly when using h:outputStylesheet as per here, but using a raw link tag was no good as I wanted to develop a custom component which loaded its own styles, i.e. it had no <head> section.

This post here indicates that if you don’t use the library attribute you can get h:outputStylesheet to work even with Primefaces themes.

In my case, I was not loading themes/images etc. so this was not an issue, but I still used the following directive and avoided use of the library attribute for simplicity:-

<h:outputStylesheet name=”uk.co.salientsoft/util/SSBreadcrumb.css”/>

This version worked. My initial attempts (which failed with a resource loading error) were as follows :-

<h:outputStylesheet name=”resources/uk.co.salientsoft/util/SSBreadcrumb.css”/>

<h:outputStylesheet name=”#{request.contextPath}/resources/uk.co.salientsoft/util/SSBreadcrumb.css”/>

In other words, with a css file stored in Eclipse under WebContent/resources/uk.co.salientsoft/util/SSBreadcrumb.css,  the above working example was correct, i.e. to load correctly, omit the context root and the resources level and use a relative reference without the preceding slash.

I did try to debug this by visiting the logger settings in Glassfish admin, then under the Log Levels tab, setting everything with JSF in it to finest! This did display an error when trying to load the resource:-

[#|2011-02-11T17:21:13.331+0000|FINE|glassfish3.0.1|javax.enterprise.resource.webcontainer.jsf.application|_ThreadID=31;_ThreadName=Thread-1;
ClassName=com.sun.faces.application.resource.ResourceHandlerImpl;MethodName=logMissingResource;
|JSF1064: Unable to find or serve resource, /SSBreadcrumb/resources/uk.co.salientsoft/util/SSBreadcrumb.css.|#]

However the error was not particularly informative as it just spat back to me the path I gave it to load. It would have been nice for it to tell me how it was mapping the path as then I could have seen the problem more easily.

Note however that using this page in Glassfish is a very convenient way to turn on logging in Glassfish, as it lists the common logger paths for you and gives a combo to select the level for each. You don’t have to go googling for the logger paths and edit a log properties file yourself. Note also that when you do this you must restart Glassfish for the log level changes to actually take effect.

No Comments »

February 2nd, 2011
7:56 pm
Primefaces Table Sorting–Common Gotchas

Posted under JSF
Tags , , , , , , , ,

Update 2/2/2011

According to this post here by Cagatay Civici, the Primefaces Project Leader, as at Primefaces 2.2M1, client side datatable is not supported and the dynamic attribute is deprecated from then on.
Seemingly it was becoming too hard to support all the table features on both client and server sides.
It is a shame that this was not documented better and more widely – the user manual still documents the dynamic attribute, and there are a number of posts about client side sorting (though in fairness they probably predate 2.2M1).

This behaviour exactly ties up with what I am seeing in my testing – the dynamic attribute does nothing, sortFunction is ignored, and all sorting is done via Ajax server side.

Original Post 2/2/2011

Having successfully got sorting working I was frustrated to find that a new simple example failed to work. Primefaces table sorting is pretty much transparent, requiring minimal effort and working out of the box. The lessons learned on this one are instructive so I summarise them below.

Details of Example and Problem

  1. The example fetched a list using JPA, stored the list in a view backing bean, then displayed it in a table with a sortable header.
  2. When the header was clicked, the up/down arrows were correctly displayed, but the data was not sorted – it was as if the request was ignored.
  3. It was not immediately obvious how the header click was handled – there was no obvious click event on the HTML element, and I could not see any Javascript running after a quick test with Firefox/Firebug. I gave up this line of attack but may look into it later as to how it all works. Some dynamic CSS pseudo classes/jQuery trickery may be involved.
  4. I was not certain as to whether the table was client side or server side/Ajax, even though it should have been client side by default. To diagnose the problem, I changed the value of the sortBy attribute in the column header to be an invalid bean property. The symptoms did not change, but an errors were logged in the Glassfish server log for each header click – “[#|2011-02-02T18:22:14.557+0000|SEVERE|glassfish3.0.1|org.primefaces.model.BeanPropertyComparator|_ThreadID=24;_ThreadName=Thread-1;|Error in sorting|#]”.
  5. This showed that the sort was being attempted but was failing due to the invalid property, which indicates that the sort was attempted server side. According to the Primefaces forum, for client side sorting, the sortBy property is not used as the displayed data is sorted.
  6. Interestingly, I would have expected Primefaces to use a client side table by default, but clearly it was not. Changing the dynamic property on the table tag to false explicitly had no effect and the behaviour was unchanged, so I will need to investigate client side tables further as for small data sets they are faster – I will update this post when I have done this.
  7. I turned on FINEST logging with Eclipselink in persistence.xml. Use <property name="eclipselink.logging.level" value="FINEST" /> to do this, and note that you need to bounce Glassfish to for a logging level change to be picked up. I noticed after this that the JPA query seemed to be rerunning very often, perhaps for every click of the sort header. This lead me to wonder if the backing bean was being recreated each time.

 

Cause and Solution

In the end, it was simply that I had not annotated the JSF backing bean as @SessionScoped (the example used CDI throughout, and did not use JSF managed beans). This meant the bean was request scoped by default, and was indeed being recreated – the sort was trying to do the correct thing, but the data was getting reloaded from the database in the original sort order each time!

Adding the correct annotation as above (and making a couple of the beans correctly implement serialisable to satisfy CDI/Weld) solved the problem.

This is a good example of where a problem cause is not immediately apparent from the symptoms.

Sample JSF page fragment showing the form containing the table

<h:form id="frmTest">   
    <util:themeSwitcher form="frmTest" outerStyle="clear: both; float: left; margin-bottom:20px;" innerStyleClass="ui-widget"/>
    <h:panelGroup layout="block" style="width:300px;">   
        <p:dataTable var="taxonomyNodes" value="#{taxonomyBrowser.taxonomyNodes}" scrollable="true"
             styleClass="clear #{fn:length(taxonomyBrowser.taxonomyNodes) lt 20 ? ‘ss-tableheader-scrolladjust-nobars’ : ‘ss-tableheader-scrolladjust-bars’}"
             height="460" > 
             <f:facet name="header">
                Client Side Sorting
             </f:facet>
             <p:column headerText="Category List"  sortBy="#{taxonomyNodes.text}">
                 <h:outputText value="#{taxonomyNodes.text}" />
             </p:column>           
        </p:dataTable>
    </h:panelGroup>
</h:form>

No Comments »

January 26th, 2011
11:48 pm
Oracle Sql*Plus Nested Scripting, Parameters and Exit Codes

Posted under Oracle
Tags , , , , ,

Update 29/3/2012 – SP2-0310 error due to backslash “\” in parameter

SQLplus has a bug whereby if call to a subscript in the same directory has a command line parameter with a backslash in it, SQLplus messes up the default directory processing and cannot find the called script. It seems to think that the backslash in the parameter is part of the called script file path.

To get around this and avoid hard coding the subdirectory in this script, I pass the subdirectory in from the caller.

Note that this issue may well be the same issue listed below in connection with the use of forward slash “/” causing default directory issues.

A second bug is also present, whereby &1 only works the first time. When used a second time, it incorrectly replaces it with the &1 parameter for the last called script, rather than using the one passed in from our caller. It may be that these &1-&n parameters are global in nature, rather than per level. To get around this, I use an explicit named define for the &1 and use that instead.

The following illustrates the problems:-

–This works ok assuming AddDomain.sql is present in the same directory as this script
@@AddDomain ‘1’  ‘!’

–This will fail with an SP2-0310 error
@@AddDomain ‘1’ ‘\’

The following fix resolves the problem:-

Calling script Main.sql

–We pass the script its own subfolder to get around an SqlPlus SP2-0310 bug, see Lookups.sql
@@Lookups\Lookups ‘Lookups’

 

Called Script Lookups.sql

/*
* SQLplus has a bug whereby if a parameter has a backslash in it,
* SQLplus messes up the default directory processing and cannot find the called script
* It seems to think that the backslash in the parameter is part of the called script file path
* To get around this and avoid hard coding the subdirectory in this script,
* we pass it in from the caller.
*
* A second bug is also present, whereby &1 only works the first time.
* When used a second time, it incorrectly replaces it with the &1 parameter
* for the last called script, rather than using the one passed in from our caller
* It may be that these &1-&n parameters are global in nature, rather than per level.
* To get around this, we use an explicit named define for the &1 and use that instead.
*
* These 2 bugs are awful – I’m not impressed!
*/

define dir=&1
 
@@&dir\AddDomain ‘1’  ‘\’
@@&dir\AddDomain ‘2’  ‘\reports’

These fixes resolve the problem.

 

Update – Parameter passing, use of “/”  and default directory issues

These issues came about when switching to the command line sqlplus utility rather than using Toad as I had before.

  1. If a parameter passed to a called script (in this case via @@) contains a slash “/”, Sql*Plus gives an SP2-0310 file open error. The error is nothing to do with opening the file, but is due to the slash. Escaping it was no help. I was using the slash as a date delimiter for a constant date string passed to the called script, so I just switched this to a dash “-“ instead and changed the to_date string in the called script to ‘YYYY-MM-DD HH24:MI:SS’. This solved the problem.
  2. If a script called via “’@@” is followed by a “/”, then the script will be called twice. Whilst it is normal to follow an SQL command with the slash, this must not be done when calling a script.
  3. When a relative path is used to call a script via the “@@” command, the default directory for the relative path is not the directory of the calling script, as you might expect, but rather the top level default directory. This is rather nasty and inconsistent in my view, but is simple to fix once you know.

Update – Return Codes from Sql*Plus

Sql*Plus can be configured to return an exit code to the calling operating system, to indicate either an OS error (such as a file open error), or an SQL error. This is extremely useful for detecting the success or failure of a script run – for example, I use it during JUnit testing when running scripts to set up a test, as there is then no need to scan log files and you can then just look at the test outcome (which is a central goal of JUnit).

To do this, just add the following at the head of your top level script. This will cause the script or any of its called scripts to abort with an exit code when it fails for any reason:-

WHENEVER OSERROR  EXIT 1
WHENEVER SQLERROR EXIT SQL.SQLCODE

The OSERROR unsurprisingly deals with OS related errors. Unfortunately, it does not appear to be possible to return the actual OS error, so in this case I have returned value of 1 which is a Windows ‘illegal function’ error, which is also what is returned when you copy or rename an invalid filename for example. The SQLERROR returns the actual Oracle error code. These codes are returned to the operating system, and for example under Windows may be detected by testing the %ERRORLEVEL% value as per normal with Windows batch files. I have yet to try this under Linux but the mechanism is similar.

Update – Verify and echo

When debugging a script, it is often useful to log each statement in the output (echo), and also to check how parameter substitution was performed (verify). To do this, just add the following to the head of your top level script. To disable them, just use off instead of on:-

set verify on
set echo on

 

Original Post

This post details some common pointers and gotchas when using nested scripts in Sql*Plus, and passing paramters to a nested script.
The examples were all executed with Toad, which is subset compatible with Sql*Plus, so the points here should work with either.

  1. Use @filepath to call a nested script with a full file path. The default file type is .sql.
  2. A common technique is to place all related scripts and sub scripts in the same directory. If you do this, use @@filename instead with just the filename, and SQL*Plus/Toad will assume that the called script is in the same directory as the executing one. This allows a collection of scripts to be moved to any desired directory and still call each other correctly with no changes.
  3. Parameters may be defined with the define  command as in the example below. Defined  parameters are global and visible to a called scripted even if defined in the calling one.
  4. Parameters are referred to using &name for a defined parameter, or &1, &2 for the first or second parameter passed to a script.
  5. When passing parameters to a script you must delimit them with spaces and must have single quotes around the parameter values, which will allow the parameter value to contain spaces. Note however that you cannot pass an empty string using two quotes ‘’ as this gives a missing parameter error. Oracle treats an empty string as a null anyway, so you should pass the null value differently, e.g. using null.
  6. If you use &name for a parameter you have not previously defined, you will be prompted for the value each time you refer to &name. If you use &&name you will only be prompted for the value the first time, and it will stick from then on and you will not be prompted. If a variable has been previously defined you just use &name all the time and the defined value is used – you will not be prompted.
  7. When defining a parameter or passing one in a call to a sub script,  put single quotes around the value. These will be stripped off when you refer to the parameter, so you will need to add them back when referring to the parameter if you are using a quoted string, for example ‘&1’ or ‘&param’. Double quotes did not work correctly with Toad (not sure about Sql*Plus) so are best avoided.
  8. Due to the above quote handling/stripping therefore, it is not straightforward/posible to add your own secondary quotes to pass a quoted string with the quotes already present. You must add the quotes in the called script, which means that you must decide whether you are passing a constant string (which will have quotes added by the called script), or an expression (which will not have quotes added). There is not a way I could find to pass a value which can either be a quoted string or expression. In practice, this tends not to be an issue and you can work within the limitation, unless you are trying to make scripts fly to the moon – don’t – they are not programs!
  9. If you want to append alphanumerics immediately after a parameter expansion, place a dot after the parameter name, and the dot will be removed, for example &param.xxxx will substitute the definition of param and concatenate it directly with xxxx. Set Concat lets you define the concatenation character to be used, period (dot) is the default.

The documentation for Sql*Plus may be found here. In addition, this is a useful site detailing a number of the features (although it gets the meaning of & and && the wrong way around!)

Simple Example of Nested Scripts with Parameter passing

Test1.sql

define Table = ‘dual’
@@test2 ‘dummy’ ‘X’

 

Test2.sql

select * from &Table where &1 like ‘&2’
/

No Comments »

January 23rd, 2011
1:41 pm
Eclipse JPA table generation fails with Eclipslink 2.1.2, Glassfish V3.0.1

Posted under JPA
Tags , , , , ,

I was attempting to create a database for a new project which just contained entities – I had imported the entity classes from Enterprise Architect and added the required annotations, getters & setters etc.

My first attempt used the following persistence.xml (I have removed most of the classes for the example)

<?xml version=”1.0″ encoding=”UTF-8″?>
<persistence version=”2.0″ xmlns=http://java.sun.com/xml/ns/persistence
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xsi:schemaLocation=”http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd”>
    
    <persistence-unit name=”Test” transaction-type=”RESOURCE_LOCAL”>
      <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

      <non-jta-data-source>jdbc/TestPool</non-jta-data-source>
      <class>uk.co.salientsoft.Test.domain.Address</class>
      <class>uk.co.salientsoft.Test.domain.AddressLine</class>
      <class>uk.co.salientsoft.Test.domain.Campaign</class>
      <class>uk.co.salientsoft.Test.domain.CampaignText</class>      
      <exclude-unlisted-classes>false</exclude-unlisted-classes>     
      <properties>
       <property name=”eclipselink.logging.level” value=”INFO” />
       <property name=”eclipselink.target-server” value=”None” />
       <!– <property name=”eclipselink.target-server” value=”SunAS9″ />–>
       <property name=”eclipselink.target-database” value=”Oracle” />      
       <property name=”eclipselink.ddl-generation.output-mode” value=”database” />
      </properties>
     </persistence-unit>
</persistence>

 Having created the database and validated the connection/datasource etc., I attempted to create the tables from  Eclipse by right clicking the project and selecting JPA Tools/Create Tables from Entities…

This resulted in the following error:-

[EL Config]: Connection(5226838)–connecting(DatabaseLogin(
    platform=>OraclePlatform
    user name=> “Test”
    connector=>JNDIConnector datasource name=>jdbc/TestPool
))
[EL Severe]: Local Exception Stack:
Exception [EclipseLink-7060] (Eclipse Persistence Services – 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Cannot acquire data source [jdbc/TestPool].
Internal Exception: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial

The error occurred even though the data source was being used outside the container as a non-jta data source (this worked previously for JPA1/Glassfish V2, allowing JPA to be used outside the container but still using a datasource defined in Glassfish). A previous post here (in the section Notes on Persistence.xml) also reports that when running outside the container, it is vital to have eclipselink.target-server defaulted or set to none. In this case, the setting caused no difference either way. After a fair bit of research/Googling, I could not find the cause of the problem, so I simply reverted to specifying the connection explicitly in persistence.xml,  without using the connection defined in Glassfish at all.

This worked correctly. I will not need to create the database very often, and it only involved tweaking a few lines in the file, so I’m happy to live with it. Here is my modified persistence.xml which uses a direct connection specified in the file. This version created the database correctly. Note that as detailed in this post here (near the bottom of the post), the property names for JDBC url, user, password and driver have now been standardised and are no longer eclipslink specific.

<?xml version=”1.0″ encoding=”UTF-8″?>
<persistence version=”2.0″ xmlns=”http://java.sun.com/xml/ns/persistence” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd”>

    <persistence-unit name=”Test” transaction-type=”RESOURCE_LOCAL”>   
    <!– <persistence-unit name=”Test” transaction-type=”JTA”>–>
   
      <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

     <!–<jta-data-source>jdbc/TestPool</jta-data-source>–>
     <!–<non-jta-data-source>jdbc/TestPool</non-jta-data-source>–>
    
      <class>uk.co.salientsoft.Test.domain.Address</class>
      <class>uk.co.salientsoft.Test.domain.AddressLine</class>
      <class>uk.co.salientsoft.Test.domain.Campaign</class>
      <class>uk.co.salientsoft.Test.domain.CampaignText</class>      
      <exclude-unlisted-classes>false</exclude-unlisted-classes>     
      <properties> 
      
        <property name=”javax.persistence.jdbc.url” value=”jdbc:oracle:thin:@localhost:1521:xe”/>     
        <property name=”javax.persistence.jdbc.user” value=”Test”/>
        <property name=”javax.persistence.jdbc.password” value=”Test”/>
        <property name=”javax.persistence.jdbc.driver” value=”oracle.jdbc.OracleDriver”/>     
     
       <property name=”eclipselink.logging.level” value=”INFO” />
        <property name=”eclipselink.target-server” value=”None” />
       <!– <property name=”eclipselink.target-server” value=”SunAS9″ />–>
       <property name=”eclipselink.target-database” value=”Oracle” />      
       <property name=”eclipselink.ddl-generation.output-mode” value=”database” />
      </properties>
     </persistence-unit>
</persistence>

No Comments »

December 12th, 2010
7:37 pm
Using the Enterprise Architect UML design tool

Posted under UML
Tags , , , , ,

Updated 11/12/2010

I’ve clarified some of the points re collection classes, code generation, and the Local Path feature.

 

Original Post (7/5/2010, 07:30)

I’m trialling Enterprise Architect from Sparx Systems at the moment, and have found the following points/tips/gotchas so far :-

Class Stereotypes

If you choose a stereotype such as entity which has its own image, this changes the appearance on the class diagram and prevents detail such asproperties and operations being listed. You can either use another stereotype (or none at all – sometimes I have not as it clutters up the simplicity of the diagram), or you can customise the appearance under settings/uml to prevent the image being used.

Collection classes and generics for relationships

The collection class to be used can be set as a global default or per class:-

  • global default – visit Tools/Options, pick Java under source code engineering in the left hand treeview pane. Click the Collection Classes button to configure the defaults. Note that you can enable generics by using e.g. Collection<#TYPE#> as the definition, where #TYPE# is replaced by the appropriate class name. This is mentioned in the help but is not easy to dig up. You can set different collection classes for Default, Ordered, and Qualified.
  • Per Class setting – open the class details (double click on the class), select the details tab, and click the Collection Classes button to configure the class in the same way as with the global defaults (including generics using #TYPE#). **Important potential Gotcha** – when setting this up, it is easy to get confused. If Class A contains a collection of Class B, then to enable a collection declaration to appear in the Java code for Class A, you must set the appropriate collection class settings on Class B, not Class A. Setting up class B will then cause that declaration to appear in Class A. Note that the per class settings overide any global default that you have applied.
  • The trigger for generation of the collection declaration is to set the Multiplicity at the appropriate end of the (aggregation) relationship between the classes. So for example, an Application might have a 0-or-1 to many relationship with AppRole, i.e. an Application will hold a collection of AppRoles. The aggregation relationship will be drawn from the AppRole class to  the Application class, such that the diamond arrowhead appears against the Application class, as that holds the collection. You would then double click the relationship, and under Source Role you would set a Multiplicity of 0..*, and under the Target Role you would set a multiplicity of 0..1. This will cause the collection declaration when the code is generated. Note that there are other settings on the source and target role pages for Role and alias, and derived, derived union, and owned. These do not appear to affect the code generation (at least in my simple examples).
  • Note that if you select ordered on the multiplicity you get the ordered type of collection class. In my case, I used global settings of Collection for unordered, List for ordered, and left the qualified as Collection. Using this I obtained a declaration of List in the generated code when I selected ordered on the multiplicity of the 0..* end of the relationship (Source Role in the above example).

Enabling/Disabling Destructor (Java finalize) calls

These can also be configured globally or on a per class basis :-

  • Global default – visit Tools/Options, pick Object Lifetimes under source code engineering, and tick or untick generate destructor. Constructors can be similarly configured.
  • Per Class setting – right click on the class and select Generate Code. Click advanced, and the same page is displayed as for the global default. Constructors/destructors are configured in the same way as above, except that the settings are per class rather than global defaults.

When Java is the target language, enabling a destructor adds a call to finalize as Java is garbage collected and does not have explicit destructors. finalize is called by the garbage collector to notify the object of garbage collection, but the call is made at the discretion of the garbage collector. For Java you would normally want to untick the generate destructor  setting.

Auto generation of package statements in Java

To configure this, you select a package in the project browser hierarchy as the package route, by selecting Code Engineering on its context menu, then picking Set as Namespace Root. Then, all packages under that root package (but not including the root package) will have their names contatenated to form the java package that is used in the code. You can use dots in the package name, so for example you could have a package heirachy of Class Model/uk.co.salientsoft/appname/domain, where Class Model would be set as the root. Then, classes in the Domain package would have a package in the code of uk.co.salientsoft.appname.domain as you would expect. Note that there are some gotchas/possible bugs around this. I only managed to get it to work when I actually created a class diagram at each level and added the next sub package onto the diagram. This looks tidy/correct anyway, and is what the example does, but it is not enforced – you can have a package hierarchy in the browser without having all the intervening class diagrams with the next subpackage on, but if you do so, it appears that package statements are not then output in the java code.

Code generation / directories

When generating code, this can be done at package level by selecting Code Engineering/Generate Source Code from a package context menu in the project browser. Ticking Include All Child Packages does just that and generates the code recursively down the package tree. You can select Auto generate files to cause the file directory paths to be automatically derived from the package hierarchy, ignoring any path set for the individual classes. However, I found this awkward to set up – ideally I wanted a java directory tree to match the package fields, but to do this seems to need a carefully crafted package hierarchy which may not match the way you want to work. For example, I had a package called uk.co.salientsoft, which ended up as a single directory name rather than being broken down into component fields. I did not want to add all the individual package levels for uk, co, and salientsoft. Also, when you Auto generate files the root path under which the tree is created is not saved and you have to browse for it every time – not pleasant. Therefore, in the end I elected not to use Auto generated files, but to set the correct file path on each class. Thus can be done by right clicking the class and selecting Generate Code, then browsing for the desired path. Clicking Save will save the path which is then used for code generation as above. Having done this, I finally acheived correct package statements in the code together with the correct directory hierarchy.

Using Local Paths

Local Paths offer a means of parameterising root directories e.g. for code generation, such that the same EAP  file can be used by multiple users with different local code generation directories.

On the surface it looks like a means of defining environment/path style variables within EA, which you then use when defining code generation locations. This is somewhat of a misconception, which is unfortunately reinforced by the section of the help on Local Paths:-

Developer A might define a local path of:
JAVA_SOURCE = “C:\Java\Source”

All Classes generated and stored in the Enterprise Architect project are stored as:
%JAVA_SOURCE%\<xxx.java>.

Developer B now defines a local path as:
JAVA_SOURCE =”D:\Source”.

Now, Enterprise Architect stores all java files in these directories as:
%JAVA_SOURCE%\<filename>

On each developer’s machine, the filename is expanded to the correct local version.

In fact, whilst you do define a local path under Settings/Local Paths…  and give the local path an ID (or variable name), you do not enter the ID anywhere when configuring directories for code generation – the local paths are applied behind the scenes in somewhat of a smoke and mirrors fashion.  In fact you do the following to set it up (example is for setting Java code generation directories directly on classes) :-

  • Select Code Generation… on the context menu for one or more classes on a class diagram. Browse for the actual desired full path for the class. You will note that at no stage is there a means to enter a variable ID in the path – you are just using the standard file browse dialog.
  • Under Settings/Local Paths… create a local path of type Java, browsing to a root directory which is either the path entered for the classes or a parent directory on the same path. Save it with a suitable name.
  • Clicking Apply Path will then apply the path to the code generation directories. It will return a count of the number of instances it applied (number of paths found). In my case, it initially found 0, but when I clicked Expand Path which reverses the process and removes your local path, and is supposed to revert to using normal full directories again – it said it removed 4 (the number of affected classes). When I clicked Apply Path again, it again found all 4, so I suspect the initial “found 0” was a bug and it had worked – confusing, especially as it is all doing stuff behind the scenes!
  • Now, to see the effect of what you have done, change your local path definition in the local path dialog for the ID you created and applied, and save the change. Now look at the code generation folders for the classes again under Code Generation…  on the context menus for the classes, and you should find that the path has changed by magic to the one you just set in the Local Path dialog! Smoke and mirrors indeed.
  • Note that normally your local path definition will just be a parent directory which is shared by all your code generation subdirectories for the classes, as there will typically be a number of different subdirectories. EA correctly changes just the parent directory part of the path.
  • You can then if desired define a number of local paths for Java, e.g. “Freds path”, “Bills path”, and apply the desired one which will then take effect. You will not see any local path IDs appearing anywhere, they are stored in the path but applied behind the scenes.
  • To switch between local paths again feels strange. You would expect that if “”Freds path” is in effect and you apply “Bills path” (which has a different definition), then the directories will  all change. They do not! What you have to do is to define “Bills path” initially to be the same definition as “Freds path”, then do an Expand Path for “Freds Path” (Whereupon you will see the correct count of classes affected). Then you can do an Apply Path for “Bills path”, which will then be applied to the same number of classes. Finally, you can amend “Bill’s path”, which is the one that currently has control, and all the class code generation directories will change.
  • One frustration of this method is that when adding new classes when a local path is in effect, you must still browse to the correct actual directory just as you would if no local path was present – you cannot enter the local path anywhere. It will however take effect ‘by magic’. In my case, I created a new class under the local path, and it immediately ‘took on’ the local path and would change its directory when I changed the local path definition, even though I had not done an ‘Apply Path’ to pick up the new class.
  • It appears therefore that new classes under the parent folder of a currently active local path pick up the effect of the local path by default.

 

My scenario is not the actual use case which will occur in practice, as I was doing this as a single user and making changes. In practice, if the EAP file was passed around, a different user would already have his source directories created according to his own standard. Nevertheless, I find the operation of this functionality to be strange, counterintuitive, and even slightly buggy in parts.

Having said that, in fairness, EA is the best UML tool I tested by far in my price range as an independent developer – $199 for the professional edition, as opposed to a 4 figure sum for other packages which I did not even bother to look at. The other features of EA are very fully functional, intuitive to use and bug free. Surprisingly, as per my other post here, all the other packages I looked at were very poor in comparison, so for my needs and price range,  and from my testing, it is still very much a one horse race.

No Comments »

December 10th, 2010
9:59 am
Date, time and calendar handing in Java

Posted under Java
Tags , , , , ,

This is rather a minefield for the unwary, and in general the various APIs in this area come in for a fair share of criticism.
Poor design, leaky abstractions and unhelpful idioms are variously cited.
However, the functionality available is comprehensive even though it can be tricky to use.

The following posts offer good advice in finding your way!

David Jenkov’s Java Date and Time Tutorial – an excellent tutorial with a number of articles on date, time, calendar handling etc.

O’Reilly OnJava.com – Making Sense of Java’s Dates – another very good tutorial

Sun Java Tutorials – Dates and Times – Sun’s Java tutorial on dates & times

Lavnish – Java Calendar vs Date – article on Lavnish’s blog

No Comments »

December 3rd, 2010
12:17 pm
Using the Primefaces Breadcrumb Component

Posted under JSF
Tags , , , ,

I did some experimentation on the best look and feel (in my humble opinion!) for this component, and found the following points along the way:-

  • By default the component was underlining all the entries. This was because all anchor tags were being underlined. The Primefaces showcase has specific rules in default.css to turn this off, so I added them too. (You might have expected this to all be done by the themes or breadcrumb css, but not the case). I just added “a {text-decoration: none;}” and “a:hover {text-decoration: underline;}” rules, but obviously there are other ways if you want other links to be underlined.
  • I then tried to place a breadcrumb in a scrolling div, to ensure that it would still work if the content overflowed. I knew that horizontal scroll bars on a breadcrumb would not look at all sexy, but wanted at least some solution for edge cases with extreme amounts of content, as by default the component truncates to the right and content is lost/not accessible. I was unable to solve this issue – the component would not play ball. I wanted to leave an inner div containing the component at a floating size, so that the control sized itself for the content, and then add a scrollable outer div with overflow:auto so that it would scroll if needed. However, the component appears to use some jQuery magic to detect the size of any fixed ancestor outer level div of the component, and then fix the control width to that size using inline styling added to one of its own inner divs by jQuery/Javascript. The only partial solution was to have a large fixed size component in a smaller outer scrolling div, but this was not good as the scrollbars were present even if not needed as the control had a fixed size.
  • The problem could probably be solved using jQuery, perhaps by modifying the jBreadcrumb jQuery component which Primefaces uses, but I did not investigate this further.
  • In the end, I reconciled myself with the default way the component works. It does have a good solution to this issue by (optionally) dynamically collapsing the entries to a designated preview width, and then expanding an entry on mouse hover (so-called preview mode). This does save a lot of space, and I decided that I could easily have more than enough entries for my needs in say an 800 pixel wide breadcrumb. Alternatively the component can be left to float entirely and rely on the browser for scrolling, but in practice there will generally be an outer container of some kind which will set a limit and trigger the above issue. In my case, this would likely be an outer level tab for a form.
  • I also decided that in practice it would be helpful to turn the preview mode on dynamically, perhaps say when the number of entries exceeded a certain number, or better still when the total character count in the breadcrumb exceeds a certain figure, as this would give good results on average and still be easy to calculate. For normal use, when there is plenty of room left in the breadcrumb, preview mode is a nuisance, but it is obviously essential when the component fills up. Ideally, this would be done when the component is filled rather than based on an entry count, but this would be tricky to calculate. Ideally this would be done dynamically by the component itself. Best of all might be a dynamic preview mode which shrinks the entries only when required and only enough to fit everything in the component.
  • Rendering the component in preview mode takes significant time when there are a lot of entries (even on my Core I7 920). This might be an issue when partially updating a page (and the component) during navigation. This is even more reason not to use preview mode unless it is really essential, as with it turned off the breadcrumb renders very quickly. On some occasions it would be possible to update the control client side, for example when just changing the underline/italic decoration on the text (see below re traversing a hierarchy) and no entries are added or removed. In this case the necessary classes could just be added and removed from the breadcrumb entries dynamically with jQuery. I have also not tried any Ajax/partial form updates with it, for example just adding or removing a single entry, but I expect the whole component will be re-rendered each time as the manual makes no mention of partial updating.
  • I experimented a bit with the expand and contract timings in preview mode. These interact with the time taken by the JavaScript to dynamically collapse the entries when the component is first rendered, so if you try to make them too fast it looks clunky. Also if the expand is too fast it can confuse you as to which entry you are hovering on, especially when there is a lot of preview compression, as you can end up highlighting the next entry along without realising it, just due to the expand/collapse effect.
  • One common use case for me is to use the component to hold the navigation path when traversing a hierarchical data set. A desirable feature would be that when you traverse back up the tree say by clicking on one of the higher levels in the breadcrumb, you do not immediately lose all the lower levels you visited. They would only be removed if you visited a higher level and then traversed down a different lower level path at some point, in which case the lower levels visited previously beyond that point would then be removed and a new path built.
  • The nice thing about the above concept is that you can repeatedly wander freely up and down a given tree path via the breadcrumb without losing any of the context, which is handy in my case as the UI deliberately only shows the current level of the tree in a table – no tree or treetable components are used in order to keep things intuitive and simple for novice users.
  • When applying this concept, it is necessary to highlight the current location in the breadcrumb, as this will no longer always be the rightmost entry. The most logical way to do this seemed to apply the same highlight as the mouse hover, which is to underline an entry. Therefore, the current entry will always be underlined, as will any other entry that is hovered over.
  • In addition, it is desirable to distinguish between the breadcrumb levels between the root and the current point from those previously visited below the current point, as the breadcrumb is no longer only showing the path to where you currently are. I tried various kinds of dimmed, disable style highlighting, but whilst it is important to make these previously visited lower level entries look different, it must also be clear that you can still click on them. In the end, my preferred solution which looks good in all the top 5 browsers and with all the Primefaces themes was to italicise the previously visited lower level entries. You therefore end up with ‘normal’ styling up to the current level. The current level itself is then shown underlined so it is clear where you are. All the entries to the right (if any) are then italicised.

The following example shows my preferred component, which is somewhat thinner than the default due to the removed padding. Examples of the different highlighting discussed above are all just coded directly into the menu options. The example also uses my theme switcher component which is not listed.

 

index.xhtml

<!DOCTYPE HTML>
<html xmlns="http://www.w3c.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core"   
xmlns:util="http://java.sun.com/jsf/composite/uk.co.salientsoft/util">
<f:view contentType="text/html">
<h:head>
    <util:themeSwitcher    outputStyle="true"
                        themeBase="/resources/themes"
                        defaultTheme="redmond"/>
<style>
    .ui-widget {
        font-size: 75% !important;
    }
    h1.header {
        font-size: 1.2em !important;
        padding: 5px;
        margin: 0px 0px 20px 0px;
        float: left;
    }
    .themeswitcher {
        float: left;
        clear: both;
        margin-bottom: 20px;
    }   
    .ss-breadcrumb {
        clear:both;
        margin: 0 0 10px 0;
        padding: 0;
        width:800;
    }   
    a {text-decoration: none;}
    a:hover {text-decoration: underline;}
    .ss-currentlevel {text-decoration:underline;}
    .ss-lowerlevel {font-style: italic;}
</style>

</h:head>
<h:body>
<h1 class="header ui-widget ui-widget-header ui-corner-all" style="">Breadcrumb</h1>

<h:form id="frmTest">
<util:themeSwitcher form="frmTest" outerStyleClass="themeswitcher"/>
<br/><br/>
    <p:breadCrumb styleClass="ss-breadcrumb" preview="false">
        <p:menuitem value="Categories" url="#" />
        <p:menuitem value="Sports" url="#" />
        <p:menuitem value="Football" url="#" />
        <p:menuitem value="Countries" url="#" styleClass="ss-currentlevel"/>
        <p:menuitem value="Spain" url="#"  styleClass="ss-lowerlevel"/>
        <p:menuitem value="F.C. Barcelona" url="#" styleClass="ss-lowerlevel"/>
        <p:menuitem value="Squad" url="#" styleClass="ss-lowerlevel"/>
        <p:menuitem value="Lionel Messi" url="#" styleClass="ss-lowerlevel"/>
        <p:menuitem value="Squad" url="#" styleClass="ss-lowerlevel"/>
        <p:menuitem value="Lionel Messi" url="#" styleClass="ss-lowerlevel" />
    </p:breadCrumb>
    <p:breadCrumb styleClass="ss-breadcrumb" preview="true" previewWidth="24"
        expandEffectDuration="400" initialCollapseEffectDuration="100"
        expandedBeginningItems="1" expandedEndItems="1">
        <p:menuitem value="Categories" url="#" />
        <p:menuitem value="Sports" url="#" />
        <p:menuitem value="Football" url="#" />
        <p:menuitem value="Countries" url="#" />
        <p:menuitem value="Spain" url="#" />
        <p:menuitem value="F.C. Barcelona" url="#"  styleClass="ss-currentlevel"/>
        <p:menuitem value="Squad" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Lionel Messi" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Categories" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Sports" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Football" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Countries" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Spain" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="F.C. Barcelona" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Squad" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Lionel Messi" url="#"  styleClass="ss-lowerlevel" />
    </p:breadCrumb>
</h:form>
</h:body>
</f:view>
</html>

No Comments »

December 3rd, 2010
9:42 am
JPA error “Class is mapped, but is not included in any persistence unit”

Posted under JPA
Tags , , , ,

I received this compile time error from Eclipse with one of my test projects which was previously fine, using Eclipse Helios with Eclipselink 2.1.0 (and container managed JPA in EJBs). The error occurred when I was autodiscovering the entities rather than listing them in persistence.xml explicitly, even when <exclude-unlisted-classes>false</exclude-unlisted-classes> was explicitly present.

Supposedly, as the annotated entity sources for the classes are in a subfolder of the parent of the META-INF folder containing persistence.xml, they should be discovered automatically. Listing the fully qualified classes explicitly in persistence.xml solved the problem, however this is not ideal as it would mean having an alternative version of persistence.xml for testing.

I googled for the problem but could not find a solution listed anywhere. For now this is just one to be aware of – I’ll stick with listing the classes explicitly and look further for a solution later on as and when it becomes a nuisance!

No Comments »