Friday, August 24, 2012

HibernateException: Found two representations of same collection

Last week one of our application workflows stopped working out of the blue. We began to see the following Hibernate exception:

org.hibernate.HibernateException: Found two representations of same collection: x.y.z.SomeClass.someAssociation
 at org.hibernate.engine.Collections.processReachableCollection(Collections.java:175)
 at org.hibernate.event.def.FlushVisitor.processCollection(FlushVisitor.java:60)
 at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:122)
 at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:83)
 at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:77)
 at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:165)
 at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219)
 at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99)
 at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
 at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
    ...  ...

Of course I searched the web for possible causes and solutions to this problem. Other people have indeed seen this exception, but the solutions they used to fix it did not make sense with how we were using Hibernate. I was baffled, I poured over our version control history to see what changeset could have possibly introduced this. Nothing. There were no changes to any of the application code that was involved in this workflow. I was stuck, so I sat on it for a while hoping I would figure it out after sleeping on it.

A few days went by until one of our developers came up to me with a problem. He had been working on shoring up our test coverage and told me another part of the application was having problems now and he would need my help to troubleshoot. I took a look at a stack trace that he had encountered:

Caused by: org.hibernate.InstantiationException: No default constructor for entity: x.y.z.SomeOtherClass
 at org.hibernate.tuple.PojoInstantiator.instantiate(PojoInstantiator.java:107)
 at org.hibernate.tuple.component.AbstractComponentTuplizer.instantiate(AbstractComponentTuplizer.java:102)
 at org.hibernate.type.ComponentType.instantiate(ComponentType.java:515)
 at org.hibernate.type.ComponentType.instantiate(ComponentType.java:521)
 at org.hibernate.type.ComponentType.resolve(ComponentType.java:613)
 at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:139)
 at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:982)
 at org.hibernate.loader.Loader.doQuery(Loader.java:857)
 at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
 at org.hibernate.loader.Loader.doList(Loader.java:2533)
 at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
 at org.hibernate.loader.Loader.list(Loader.java:2271)
 at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:452)
 at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)
 at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
 at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1268)
 at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
This immediately struck me as problematic because I knew that SomeOtherClass was an @Embedded Hibernate entity and required a public no-arg constructor. I opened up the Java class and saw this:
@Embeddable
public class SomeOtherClass implements Comparable {

  private Integer listTypeId;

  @Column(name = "listContactId")
  private Integer contactId;

  public SomeOtherClass(int contactId, int listTypeId) {
    this.contactId = contactId;
    this.listTypeId = listTypeId;
  }

  public Integer getListTypeId() {
    return listTypeId;
  }
  ...
Someone had added an overloaded constructor to take two arguments. This of course shadowed the default no-arg constructor which was no longer part of the API. After some digging and discussion with my teammate, we saw that the overloaded constructor had been added to make unit testing the class easier. The fix was as simple as re-adding the public no-arg constructor. After I did this, I thought I might as well test the first workflow that I was stumped on and see if this changed the behavior of that. You know what? It did. The first workflow began working again. I was excited and also slightly enraged -- and so it goes with Hibernate.

Monday, August 20, 2012

Formatting Text in Java

Working with structured text fragments like SQL and XML in Java can be a hassle since Java doesn't support multi-line strings.  In the case of SQL, a developer usually writes the query in a database tool like Toad, SSMS or pgAdmin in a readable format and then pastes it into their Java code.  After that happens, you immediately have to choose one of the following options:

Option 1: Join the lines so the statement becomes one long String literal

  • Pro: the text is easy to copy back into the SQL tool and reformat in the tool
  • Con: the Java code isn't readable for anything but the simplest query
  • Con: file diffs can be difficult to compare and code review during maintenance, this is expecially true when you're trying to track down bind variables
Option 1: String line string containing the query

Option 2: Copy the query into the Java file and try to preserve formatting by concatenating lines together

Option 2: before code formatter
  • Pro: the SQL is somewhat readable in the Java file and file diffs are easy to compare during maintenance and code review
  • Con: the query is difficult to copy out into the SQL tool without doing a search and replace for the Java String parts (+ and ")
  • Con: invoking an IDE formatter on the Java can be a frustrating because the formatter may mangle the concatenations 
Option 2: after code formatter, yuck!












Since both of these approaches are cumbersome, I'd like to suggest another alternative you may not have considered.  This approach, while not exactly a silver bullet solution, builds on Option 2 to make maintaining structured text a little less painful in Java:

Option 3: Leave the query formatted, but pad it out on both sides with whitespace.  

Option 3: Block select mode

  • Pro: you can copy and paste the text to and from your SQL tool using the Block Selection feature of your IDE or text editor
  • Pro: the text is readable, easy to code review and maintain
  • Pro: the IDE code formatter won't mangle the lines like option 2 because they are wide enough to ensure that the lines aren't joined
  • Con: Its still a hack and until Java gets multi-line string support, this may be the best we can do outside of externalizing the SQL in another file.

Saturday, August 18, 2012

Eclipse Juno, Maven, M2E and EGit Compatibility Problem and Solution

If you've upgraded to Eclipse Juno recently, you're likely having trouble using the following plugins in harmony with each other:
  •     EGit
  •     m2e
  •     m2eclipse-egit connector
If you try to install the m2eclipse-egit connector, you'll get an error message similar to the following:

Operation details
  Cannot complete the install because of a conflicting dependency.
  Software being installed: Maven SCM Handler for EGit 0.14.0.201110251725



The problem is that the m2e connector available on the update site through the marketplace is not compatible with the latest version of EGit that ships with Eclipse Juno.  To get around this problem, you'll need to install the most up to date m2e-egit connector version manually.  To do this, perform the following steps:

  1. Click Help
  2. Install New Software
  3. Uncheck the box labeled Group items by category (this step is important or you won't see the connector in the table)
  4. Paste in this URL http://repository.tesla.io:8081/nexus/content/sites/m2e.extras/m2eclipse-egit/0.14.0/N/0.14.0.20120701011/
  5. Finish the plugin install wizard and restart the workspace


Its worth noting that this problem exists for the other connectors as well, i.e.the subversion connector. If you're still having trouble, the following thread may help:


http://dev.eclipse.org/mhonarc/lists/m2e-users/msg02748.html

Tuesday, January 25, 2011

Unit testing private methods like a Software Engineer

Right now, there are three conventional schools of thought on unit testing private methods:

  1. Make the private method protected to facilitate unit testing
  2. Use some reflective utility to make the private method accessible from the test
  3. Don't unit test private methods since they aren't part of the public API

The first two obviously break encapsulation which leads to tight-coupling, which, as we all know, leads to less maintainable code and probably gang violence.  Because of this, I consider these solutions to be a hack or a kludge:

(n) kludge: a badly assembled collection of parts hastily assembled to serve some particular purpose (often used to refer to computing systems or software that has been badly put together)

And since the title of the entry contains the phrase 'like a Software Engineer', we'll distance ourselves from either of these approaches.

But before we get too far, if you're working with properly defined abstractions the third approach is actually viable.  If you have cohesive classes that follow the single responsibility principle, your private methods can probably be implemented by public methods on another class.  Read that sentence again if you didn't understand it the first time.  I've heard engineers say things along the lines of "That's great, but it doesn't really work in my scenario."  Generally, this is an indication that the abstraction needs to be reevaluated, and likely refactored into more granular chunks of complexity.

Now, if you still want to unit test a private method, there is another method you can use that won't break your black box.  Let's walk through an example.  Note that this is extremely contrived, but I hope you can see how the principle applies:

1) Examine your production code.  In this case we have a Calculator class with a private square method we want to test which is being called from getSquare:

public class Calculator {
  ...
  public String getSquare(int x) {
    return "The square of the number is: " + square(x);
  }
  ...
  private int square(int x) {
    return x * x;
  }
  ...
}

2) Create a test class to test the public interface. Our public interface is the getSquare method of the Calculator class:

public class CalculatorTest {
  Calculator calc = new Calculator();


  @Test
  public void getSquareOf6() {
    // TODO
  }
}

3) Create a method in your test class that has the same implementation contract as the private method you'd like to test.  This is the interesting part, the code in your test might even be the same as the private method's production code, but for the sake of the example, its not.  We want to emphasize testing the contract semantic, not how the semantic is fulfilled:

public class CalculatorTest {
  Calculator calc = new Calculator();


  @Test
  public void getSquareOf6() {
    // TODO
  }


  // Different implementation, same contract semantics
  private int doSquare(int number) {
    int x = 0;
    for(int i = 0; i < number; i++) {
      x += number;    
    }
    return x;
  }
}

4) Create a series of tests to test the new method you've created.  This will ensure that you've validated the correctness of your implementation.  These are the unit tests for your private method.  Didn't catch that?  Well, you're going to test your private method by testing a completely different method and comparing the results of the well-tested method with the results of your untested private production code method.

public class CalculatorTest {
  Calculator calc = new Calculator();


  @Test
  public void getSquareOf6() {
    // TODO
  }


  private int doSquare(int number) {
    int x = 0;
    for(int i = 0; i < number; i++) {
      x += number;    
    }
    return x;
  }


  @Test
  public void doSquare2() {
    Assert.assertEquals(4, doSquare(2));
  }


  @Test
  public void doSquare4() {
    Assert.assertEquals(16, doSquare(4));
  } 
  // More tests
}

5) At this point, we're pretty confident in the code we wrote within the test class, but we still have yet to test our private method through the public interface provided by the production class:

public class CalculatorTest {
  Calculator calc = new Calculator();


  @Test
  public void getSquareOf6() {
// expected, actual
    Assert.assertEquals("The square of the number is: " + doSquare(6), calc.getSquare(6));
  }


  private int doSquare(int number) {
    int x = 0;
    for(int i = 0; i < number; i++) {
      x += number;    
    }
    return x;
  }

  // Other tests, etc. truncated for clarity
}

In summary, we've tested the public interface of our production code, but we've also written tested code to validate the implementation of the public method without exposing the implementation details.  As I mentioned, generally its preferable to ensure that you're using the proper abstractions, in this contrived case the number squaring behavior might have been abstracted behind a class that implements behaviors dealing with exponents.  Also, our public method was pretty straight forward as well.  Your method might return a more complex object, but this technique will still apply.

This method may also take a little practice, but I think you can see the benefit provided by preserving encapsulation and the correct abstraction supplied by the interface of the public class.

Thursday, September 23, 2010

Protected Java Member Subtleties

Every legitimate Java developer knows there's four access levels and three access modifier keywords in Java.  If you were an instructor and had to pick one to give a quiz on, which one would it be? Ironically, the default level is probably the access level you use the least (cue the sad tuba).  But what about protected?  Take this subtlety you might not have thought about into consideration. Here is our superclass:

package org.iaea;

public class EnergySource {
    protected long efficiency;
}



Consider the following variation (1) of a subclass:

package org.iaea;

public class UraniumBasedReactor extends EnergySource {

    public void bringOnline() {
        EnergySource other = new EnergySource();
        this.efficiency = 0;
        other.efficiency = 12; // Works Fine!
    }

}

and now this one (2):

package org.iaea.uranium;

import org.iaea.EnergySource;

public class UraniumBasedReactor extends EnergySource {

    public void bringOnline() {
        EnergySource other = new EnergySource();
        this.efficiency = 0;
        other.efficiency = 12; // Compile Error!
    }

}


Notice that the only difference is the subclass package in the second variation leading to a compile error.  The IS-A EnergySource relationship still holds for our subclass, but we can't see protected members of other instances any more.  In this case, let's check the Java Language Spec:

6.6.2 Details on protected Access
A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.


This seems confusing at first.  Some of the other sections of the spec seem to imply that both of these examples are valid:

6.6.2.1 Access to a protected Member
Let C be the class in which a protected member m is declared. Access is permitted only within the body of a subclass S of C. In addition, if Id denotes an instance field or instance method, then:
  • If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S.
  • If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.
Certainly, one could argue that the second clause of 6.6.2.1 holds true for our case as it only stipulates types, not instances.  However, the key here is figuring out what code that is responsible for the implementation of that object (6.6.2) means.  Well evidently, it means that since other is not the same instance as this that we don't have access to other's protected members when we're not in the same package.  Other examples in the JLS seem to support this conclusion as well.  However, if you were to ask me to rank the access levels in order of most restrictive to least, I would say:

  • private
  • default
  • protected
  • public

And generally, Sun and Oracle would agree. But this seems to be a corner case where we see that protected actually carries an interesting visibility restriction scenario that none of the other access levels could create.

Wednesday, September 15, 2010

Interesting Note on Glassfish v3 Installer

I decided to setup a Glassfish V3 environment to evaluate it for a project I'm working on. I saw this Oracle annotation in the installer and thought it was a little ironic:


"Created by Oracle with contributions from the Glassfish community". A true sign of the times.  Apparently you can buy something and claim that you created it.

Friday, August 27, 2010

Maven 2 Project Dependency JAR Corruption

Earlier today, I was experiencing a weird deployment problem using the Jetty plugin with Maven. Some of the dependency JARs appeared to be corrupted. Because of this, my application was throwing the following exceptions. If you see this issue, try deleting the archives and allow maven to re-download the dependencies.

2010-08-27 19:29:12.240:WARN::Failed to read file: C:\Users\jcone\.m2\repository\antlr\antlr\2.7.6\antlr-2.7.6.jar
java.util.zip.ZipException: error in opening zip file
at java.util.zip.ZipFile.open(Native Method)
...
2010-08-27 19:29:12.245:WARN::Failed to read file: C:\Users\jcone\.m2\repository\dom4j\dom4j\1.6.1\dom4j-1.6.1.jar
java.util.zip.ZipException: error in opening zip file
at java.util.zip.ZipFile.open(Native Method)
...
2010-08-27 19:29:12.248:WARN::Failed to read file: C:\Users\jcone\.m2\repository\javax\transaction\jta\1.1\jta-1.1.jar
java.util.zip.ZipException: error in opening zip file
at java.util.zip.ZipFile.open(Native Method)
...

Friday, January 8, 2010

Deploying Oracle ADF 11.1.1.2.0 to a standalone WebLogic 10.3.2 instance

Introduction


First of all, this is really quite a challenge.  Oracle provides documentation for performing this deployment but it assumes you're deploying the application to an EAR file constructed using Oracle JDeveloper.  Since that never happens in the real world (because we all use things like build management systems which swap property files in and out and automatically setup datasources), here are some things that might be good to know, especially if you're doing this as part of an upgrade from a previous version (like 11.1.1.1.0):

Prerequisites


You'll need to install the ADF runtime to the WLS 10.3.2 instance you're deploying to.  There are literally dozens of documents and blogs describing those so I won't go into detail here.

EAR Structure


Generally, when we talk about ADF we're discussing a web application module and maybe a couple of EJBs.  For a web application, you'll want to make sure the following lines are contained in your weblogic.xml file:

<library-ref>
<library-name>adf.oracle.domain.webapp</library-name>
</library-ref>
<library-ref>

<library-name>jstl</library-name>
<specification-version>1.2</specification-version>
</library-ref>
<library-ref>

<library-name>jsf</library-name>
<specification-version>1.2</specification-version>
</library-ref>

Also, be sure to include the following in your weblogic-application.xml file:

<library-ref>
<library-name>adf.oracle.domain</library-name>
</library-ref>


These two stanzas will allow your application access to the shared libraries you installed as part of the prerequisite step.  In doing so, you shouldn't need to package any of the ADF JAR files directly in your EAR.  If you do so, WebLogic will complain and your log file will start to look very busy.

Startup Classpath


You'll also need to make sure your managed server's startup classpath looks something like this:
$WLS/jdk160_14_R27.6.5-32/lib/tools.jar
:$WLS/utils/config/10.3/config-launch.jar
:$WLS/wlserver_10.3/server/lib/weblogic_sp.jar
:$WLS/wlserver_10.3/server/lib/weblogic.jar
:$WLS/modules/features/weblogic.server.modules_10.3.2.0.jar
:$WLS/wlserver_10.3/server/lib/webservices.jar
:$WLS/wlserver_10.3/server/lib/wlcommons-logging.jar
:$WLS/modules/org.apache.ant_1.7.0/lib/ant-all.jar
:$WLS/modules/net.sf.antcontrib_1.0.0.0_1-0b2/lib/ant-contrib.jar
:$WLS/oracle_common/modules/oracle.jrf_11.1.1/jrf.jar
:$WLS/wlserver_10.3/server/lib/xqrl.jar


Where $WLS is your WebLogic installation.  The big one here is jrf.jar.  This is a JAR file with zero classes in it.  Basically it just contains a JAR manifest (MANIFEST.MF) that has Class-Path entries for all the ADF dependencies.

Apache Commons Logging


Unfortunately, jrf.jar introduces a dependency on commons logging 1.0.4 which contains the memory leak problem and lacks the diagnostic tools contained in JCL 1.1.1.  The end result is that this will cause problems if you try to package commons logging with your enterprise application.

References



WebLogic 10.3.2 Documentation

Commons Logging Documentation

Oracle ADF 11.1.1.2.0 Documentation

As an aside, I've found the best thing to do is open Oracle JDeveloper 11.1.1.2.0 and use the help with the IDE to link out to other documentation.  Often times it can be impossible to Google for Oracle  software documentation because any results don't contain enough information about which version they refer to.  Using the embedded help to click out seems to be the best way to get accurate information.

Friday, November 27, 2009

Debug logging in Java

Some people really dislike debug log messages in production code. Though they can be extremely useful, I think a lot of developers are turned off to the fact that when logging is done poorly, it really makes the code look like a mess. For example, we've all seen code like this:


   public class PressureValveController {
   ...
      public void closeValve() {
      ...
         LOG.debug("my out temp" + temperature + " press: " + 
            pressure + " and flowRate " + flowRate);
      }
   }


The above is nothing more than 'stream of consciousness' logging. Its funny how after about 20 years of schooling, trained software engineers still refuse to write complete sentences. The developer basically just dumped the stack to debug a specific problem they were having. This is one of a combination of factors that make code painful to read when logging is involved:
  • poor/no grammar
  • multiple log statements per method
  • excessive string concatenation

I think there are a couple of things you can do to make this more useful. First of all, leverage the features of the language to make it more readable. I like to create a helper method for logging in Java:


   ...
   private void debug(String message, Object... args) {
      if(LOG.isDebugEnabled()) {
         LOG.debug(String.format(message, args));
      }
   }


The next thing to do is to follow certain guidelines with respect to uniformity and sentence structure. For example:


   public class PressureValveController {
      ...
      public void closeValve() {
      ...
         debug("Closing valve with output temperature: %d, pressure: %f PSI, and a flow of %f CFM.", temperature, pressure, flowRate);
      }
   }



I don't know about you, but I think this ends up being a lot more useful in terms of code clarity and actual output. Its interesting that we wouldn't tolerate a user interface with messy output, why do we tolerate this in a log file?

Monday, November 16, 2009

BlackBerry Development Gotchas

If you're developing for the Blackberry, you've likely tried the BlackBerry JDE Plugin for Eclipse.  However, I've noticed a couple of things that you might want to know before you get going:
  • In the 4.5 component pack, calls to getName() from the static .class instance (i.e. Object.class.getName()) can cause weird preverification errors that don't manifest themselves outside the IDE.
  • If you have a project that uses the maven layout, you'll want to be aware that the BlackBerry tools are going to rewrite your sourcecode to the ${basedir}/src directory for preverification.  This means that you'll see multiple copies of the same Java file in a single project.
  • Its basically impossible to work with a 3rd party JAR file inside the IDE.  If you can, get the source for the JAR and import it into your project to be built alongside your application code.
  • Preprocessor support exists, but its kind of weird.  If you install the 4.7 component pack, you'll be able to build using the preprocessor and the 4.7 APIs on a 4.5 device with no errors in the 'Problems' window (assuming your preprocessor defines actually exclude 4.7 code).  However, you will still see red errors in the code editor window for APIs that don't exist in 4.5 (after you switch back to the 4.5 component pack)
  • Since JUnit uses reflection, having your unit tests and your BlackBerry code in the same project is basically impossible.  Its easiest to create a separate project for this.
  • The JDE spits out all the build time artifacts to the top-level project directory.  This can be annoying as you'll find yourself continually adding things to .cvsignore.