Pencils Down

This weblog is about my experiences in software development

Browsing Posts tagged Java

I have a screen with a series of commandButton’s. They all should call various action methods back in the controller. Some of the command buttons used images – they worked. Others just had values for the buttons – they did not work.

Adding onclick showed the buttons were working, they just were not calling the actions.

Several misguided google’d references mentioned changing the behavior of the ui callback setting in web.xml. I tried that and it made no difference.

Finally I noticed that I was missing the id attribute on the buttons. Adding different id’s for each of the buttons fixed the problem – the buttons now invoke the methods as expected.

I had thought that icefaces added default id’s where necessary, but there may be a glitch when you have an assortment of fields of the same type.

This is a really ugly exception thrown by Oracle from the bowels of Hibernate. In my case I had just added a table to the mapping so I at least had some idea where to look.

Looking at the integer values in the table I went through and verified each as correct in the db, mapping, entity and sequence. No luck there.

Poking around the internet though told me the error probably had nothing to do with a LONG mapping and could be ANY size mapping on any field. It’s a generic sizing error.

Luckily the table I created only had a few fields so I was able to narrow done the problem pretty quickly. In my case a VARCHAR2(4000) was attempted to be stored with much more. So, the String in the Java entity had to be controlled to make sure it was small enough.

It’s not much, but thought I would pass the info along and maybe save you some time.

A lead developer with expertise in database systems was recently promoted to project lead working in a team that was short-handed.  It seemed like a reasonable fit, at first.

Since then Ihave learned:

- The project is a modern Java web app (they hired 2 junior C (not C++ or GUI) developers from other units)

- There is no architecture, so the developers are doing things like investigating the use of Spring or not.

- The project must be shipped in a few months.  This appears to be a collosal communications screw up: the contract says delivery so many days after signing, the client delayed signed for months, once signed the client assumed the clock had been ticking all along the signing was just a formality.

- The company we work for is strictly waterfall development with very long test cycles.  Given the expected ship date the project needs to go into test phase in a couple of weeks in order to meet their delivery date (per contract) or face penalties.

- Since our company is very concerned with security all 3rd party software used (tomcat, Spring, commons library, etc…) must get approval from lawyer types who go over the specific license agreement for the software involved.  Especially of interest is anything developed by non-US parties.

- There are no written requirements beyond a few paragraphs in the contract.

- There is no UI-design, it is being done by the aforementioned C developers.

- Like everyone else in the world there are constraints on hiring, so it is likely the project will not get a Java developer to help out.

That’s about all I can think of so far.  I am always amazed this kind of silliness still goes on in the world.

This error is a catchall for anything else that might be wrong with your test class.  First make sure any of the below problems are not occurring. 

Your unit test code is running JUnit4.  At least one test method must have the @Test annotation.  Otherwise this error occurs.

If the class you are testing has @Required setters for Spring injections they must be set otherwise JUnit will mask the missing required exception as a no runnable methods exception.

If you are initializing your mock objects outside of the @Begin method you will get this error.

If you are attempting to mock the same class more than once you will get this error.

You may have recieved an exception in Hibernate like:

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session…..

This is likely caused by your code doing something like:

session.get()

object.setSomething(value)

session.update()

The session.update() call is attempting to attach an object to the Hibernate session.  This is done by the object id.  If you already have an object with the same id associated with the session (i.e. maintained by Hibernate) you get this error.

You have two choices:

1) Don’t call update on the object.  It is already being maintained by Hibernate.  There is no need to do so.  A later flush() will push any changes recorded in the session to the database.

2) If you can not tell if the object is associated with the session (likely in a long user scenario) call merge() instead.  Merge() takes the instance passed and merges it with any object of the same id associated with the session.  Note, if you plan on using the object again you must use the object returned by the call to merge().  The instance object passed to merge will not be updated.

Our team lead just hired another contractor from the same agency I am working through.  The contractor went through the interview rounds (full-time’s only) including the team lead and group lead.

Per the team lead the developer has lots of experience with Java, JSF, SOA, etc…  All the stuff we need on the team

The guy talks, a lot.  This is just a personality trait that irks me.  So, maybe he’s ok anyway.

Then I overhear the conversations he’s having with other developers (see talks a lot above) and some of the questions he has asked me:

  • When a screen (from the functional spec) has multiple checkboxes does that mean the user can select multiple items?
  • Similar when a screen has multiple radio buttons does that mean the user can select only one?
  • Do I need the JDK installed to compile the application?
  • Are all of the user actions affecting the database?

I guess the worst part is I bet he is getting the same hourly rate (or better) than I am.

After much searching around the Internet I have come to the conclusion that Hibernate really doesn’t support self-referencing tables. The typical example is something like this table:

Table Category
---------------
categoryId int
name varchar(50)
parent int

In this example the Hibernate code would be something like:

Category parent = ...
Category child = ...
child.setParent(parent)
dao.create(child);
//this does not appear to actually do anything in a self-referencing table
parent.getChildren().add(child);
dao.saveOrUpdate(parent);
session.flush();

//and then later on

Category category = categoryDao.something();
for(Category child:category.getChildren()) {
  //do something with each child
}

Notes:

  • Since the reference is in the same table, the above add() to the parent children does nothing.
  • The setParent() call is just setting the parent column directly in the Category object – no database action is taking place.
  • Calls to getChildren() are doing a simple query unlike other getObject ORM calls in Hibernate
  • Calls to getParent() are also doing abnormal ORM calls

All of the above code ‘works’. It just doesn’t work like anything else really in Hibernate.

IceFaces Rocks!

No comments

IceFaces is a Java AJAX framework (http://icefaces.org).  Open-source.  Through it’s live connectivity to the DOM on the client ALL interactions are performed in sequence to a back-end supporting beans.

IceFaces has all the built-ins you would expect to be able to build a RIA app.  The best part is it works and even better: the tutorials on the site work!  There are so many open source frameworks out there with very little documentation.  More typically the x.org site supporting your open source framework has limited, theoretical documentation – think of Hibernate or Spring – both excellent frameworks, but very sparse documentation on how to do regular, everyday things.  So, you end up poking around on the network and typically find several leads that are just wrong.

Such a pleasure to use a tool that you don’t have to waste time on redeveloping the wheel every day.

We have a case where most of our tables have composite ids.  This means a key with multiple parts.  While fairly common in the database world, Hibernate appears to prefer that it’s users NOT have complex keys.  The mapping definitions don’t really allow for this to occur (e.g. you can’t specify a generator class in a composite key)

We had thought about generating a single column key (something like a hash of the composite elements), but that just seemed wrong.  I always thought a database should model reality, not some arbitrary manifestation to get a tool to work.

In this example we have two tables that look like this:

Table A
——-
A_NAME VARCHAR(200)
A_ID INT
attributes ….

Table B
——-
B_NAME VARCHAR(200)
B_ID INT
attributes ….

They both have composite ids.  A helper table is generated that provides the many-to-many mappings for the two:

Table AB
——–
A_NAME VARCHAR(200)
A_ID INT
B_NAME VARCHAR(200)
B_ID INT

Using standard Hibernate reverse engineering we end up with the following mappings:

Table A Mapping
—————

<composite-id name=”id” class=”path.to.entity.classes.AId”>
 <key-property name=”aId” type=”integer”>
  <column name=”A_ID” precision=”22″ scale=”0″ />
 </key-property>
 <key-property name=”aName” type=”string”>
  <column name=”A_NAME” length=”12″ />
 </key-property>
</composite-id>

<set name=”bs” table=”table_ab” cascade=”all” inverse=”true”>
 <key>
  <column name=”A_NAME” not-null=”true” />
  <column name=”A_ID” not-null=”true” />
 </key>
 <many-to-many class=”path.to.entity.classes.B”>
  <column name=”B_NAME” />
  <column name=”B_ID” />
 </many-to-many>
</set>  

Table B Mapping
—————

<composite-id name=”id” class=”path.to.entity.classes.BId”>
 <key-property name=”bId” type=”integer”>
  <column name=”B_ID” precision=”22″ scale=”0″ />
 </key-property>
 <key-property name=”bName” type=”string”>
  <column name=”B_NAME” length=”12″ />
 </key-property>
</composite-id>

<!– CRITICAL – Only one side can have inverse=true, the other must have inverse=false –>
<set name=”as” table=”table_ab” cascade=”all” inverse=”false”>
 <key>
  <column name=”B_NAME” not-null=”true” />
  <column name=”B_ID” not-null=”true” />
 </key>
 <many-to-many class=”path.to.entity.classes.A”>
  <column name=”A_NAME” />
  <column name=”A_ID” />
 </many-to-many>
</set>  

Table AB Mapping
—————-

<many-to-one name=”a” class=”path.to.entity.classes.A” update=”false” insert=”false” fetch=”select”>
 <column name=”A_NAME” not-null=”true” />
 <column name=”A_ID” not-null=”true” />
</many-to-one>
<many-to-one name=”b” class=”path.to.entity.classes.B” update=”false” insert=”false” fetch=”select”>
 <column name=”B_NAME” not-null=”true” />
 <column name=”B_ID” not-null=”true” />
</many-to-one>

Be sure to note use of the inverse attribute in the A and B mappings: only one side of a many-to-many can be the ‘owner’ of the relationship.  The owner is denoted with inverse=true setting.  The other side of a many-to-many MUST be inverse=false.  It is completely arbitrary which is the owner, but Hibernate will not work unless there is only one.

So, once the mapping is cleared up we produce fairly normal Java code to create a many-to-many relation:

A a = new A();
a.setXYZZY(“various attributes”);
AId aid = new AId();
aid.setPKPart1(“string”);
aid.setPKPart2(4);           
a.setId(aid);

session.save(a)

B b = new B();
b.setXYZZY(“various attributes”);
BId bid = new BId();
bid.setPKPart1(“string”);
bid.setPKPart2(12);           
b.setId(bid);

session.save(b)

a.getBs().add(b);
session.saveOrUpdate(a);

b.getAs().add(a);
session.saveOrUpdate(b)

session.flush();

Just to be sure, note we are setting the composite id fields manually.  In Oracle this can be done by accessing a Sequence.  Other databases have built-in row ids.

After looking at several posts on the Internet that had various degrees of correctness we finally got this to work. So I thought it would be good to share. In the specific case we were using a stored procedure to access a sequence number (yes, it is outside of Hibernate’s cachable domain).

First, we place the stored procedure definitions inside of a new mapping file:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<sql-query name="getNextSequence" callable="true">
<return-scalar column="NextVal" type="integer"/>
{ call get_next_sequence(?,:tableName) }
</sql-query>
</hibernate-mapping>

Notes:
- the first argument of the stored procedure is actually an OUT parameter from Oracle.
- the actual name of the output ‘column’ must be specified in the return-scalar field

Then the Java code becomes pretty standard:

Session session = TestHibernateSessionFactory.getSession();
Query query = session.getNamedQuery("getNextSequence");
query.setString("tableName", "Table_X");
Object result = query.uniqueResult();
System.out.print(result);