Saturday, January 11, 2014

Miscellaneous problems with GWT/Spring/Hibernate/Eclipse in web development


Debug breakpoints are not triggered in GWT client package.

Reason: Debug mode form GWT client package only works in the Development mode. In the production mode, the GWT client side runs the compiled Javascript that has lost the information of the debug breakpoints.

Solution: Use the URL of http://127.0.0.1:8888/myproject.html?gwt.codesvr=127.0.0.1:9997 -- note: the "?gwt.codesvr=127.0.0.1:9997" part refers to the code server running the Java version of the client package.


When using GWT SimplePager setPageSize() for the paging of a CellTable, only the first page has data. Pressing the Next button shows no more data and pressing the Back button may raise a null-pointer exception.

Solution: Use a ListDataProvider<T> to inject the data of the list to the widget, e.g.
  CellTable<DataObj> cellTable = new CellTable<DataObj>();
  ...
  cellTable.addColumn(...);
  ...
  cellTable.setRowData(0, dataList);
  cellTable.setRowCount(dataList.size(), true);
  ...
  // Add a pager
  SimplePager.Resources pagerResources = GWT.create(SimplePager.Resources.class);
  SimplePager simplePager = new SimplePager(TextLocation.CENTER, pagerResources, false, 0, true);
  ...
  simplePager.setDisplay(cellTable);
  simplePager.setPageSize(10);
  ...
  // Must use ListDataProvider for correct paging.
  ListDataProvider<DataObj> dataProvider = new ListDataProvider<DataObj>();
  dataProvider.addDataDisplay(cellTable);
  dataProvider.setList(dataList);


org.hibernate.MappingException: Repeated column in mapping for entity: ... column: ... (shold be mapped with insert="false" update="false")

Reason: The column is used as JoinColumn too. If different values are set for the "Column" and "JoinColumn", it will cause inconsistence. Hibernate only allows the changes on one place when doing the insertion or update.

Solution: Use "insertable=false, updatable=false" in all but one mapping, e.g.
  @Column (name="...", insertable=false, updatable="false")
or
  @JoinColumn (name="...", referancedColumnName="...", insertable=false, updatable=false)


Hibernate criteria.list() returns empty list.

Solution: Add
  <property name="packageToScan" value="package.to.scan.for.the.entity.classes" />
to
  <bean id=sessionFactory" 
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

GWT WindowBuilder cannot find the CSS file. Trying to add new style generates this error message "There are no CSS files referenced from modules HTML."

Reason: The WindowBuilder cannot access the CSS under the "war" directory.

Solution: Create a new subdirectory where the ???.gwt.xml locates. By default, GWT recognizes the directory name as "public". If we want to use another name, such as "css", we need to add
  <public path="css">
into the ???.gwt.xml file. We also add the file name of the CSS file to the ???.gwt.xml file
  <stylesheet src="???.css" />
The GWT compiler will copy all the files under "public" to "war/my-project-name" directory.

Exception from Hibernate 4 when calling sessionFactory.getCurrentSession(): Caused by: org.hibernate.HibernateException: No Session found for current thread.

Solution: Verify that the configuration for transactionManager is correct.  Add @Transactional to the method that calls sessionFactory.getCurrentSession().

Exception from Hibernate: Caused by: org.hibernate.ObjectNoFoundException: No row with the given identifier exists: [...]

Reason: The Entity has a one-to-one, one-to-many etc mapping and the referred Entity has no data for this reference. For example, the User table can be joined to the ContactInfo table. For a user that does not have a record in the ContactInfo table, such an exception will be thrown.

Solution: Use the @NotFound(action=NotFoundAction.IGNORE) annotation for the reference member. The member will then be set as null in the returned Entity.

Associated entities are not saved when saving an entity.

Reason: By default, we have to explicitly save each one.

Solution: Use CascadeType for the mapping, e.g. @OneToOne(cascade=CascadeType.PERSIST), @OneToMany(cascade=CascadeType.ALL), etc. Hibernate will then automatically propagate your action to the associated entity.

Exception: Caused by: org.hibernate.AnnotationException: No identifier specified for entity

Reason: Annotation @Id is missing. Each @Entity needs an @Id. It is the primary key in the database.

To automatically generate column names in uppercase from property name.

Solution: Create a naming strategy from hibernate DefaultNamingStrategy:
  public class MyNamingStrategy extends DefaultNamingStrategy {
    @Override
    public String propertyToColumnName(String propertyName) {
      return proertyName.toUpperCase();
    }
  }
In the configuration XML file, add:
  <property name="namingStrategy">
    <bean class="package.path.to.MyNamingStrategy" />
  </property>

OneToMany unidirectional mapping throws exception: org.hibernate.MappingException: Unable to find column with logical name: ??? in org.hibernate.mapping.Table(???) and its related supertables and secondary tables.

Reason: The elments of "name" and "referencedColumnName" in JoinColumn annotation depend on the context (see http://docs.oracle.com/javaee/6/api/javax/persistence/JoinColumn.html).

Solution: In my case, I need to switch the values of them. And refeencedColumnName should refer to a PHYSICAL column in the source table.

When primary key is used as @OneToOne mapping and @JoinColumn, an exception is thrown: Caused by: java.lang.NullPointerException at org.hibernate.type.descriptor.java.AbstractTypeDescriptor.extractHashCode (AbstractTypeDescriptor.java:88)

Solution: Restructure the code to make sure the target object is persisted first so that the primary key is known when persisting the object in question.

Exception: Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist.

Reason 1: Inconsistency issue. E.g. Class A has a @OnetoMany reference to class B, while class B has a @ManyToOne reference to class A. We need to satisfy both side of the relationship before performing persistence, i.e. objA.getB().add(objB); objB.setA(objA).

Reason 2: Manually set the value for the field of GenerationType.AUTO.

Exception: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role ...... could not initialize proxy - no Session

Solution: use Hibername.initialize() to initialize the proxy before the session is closed.

Exception: com.google.gwt.user.client.rpc.SerializationException: Type 'org.hibernate.collection.internal.PersistentBag' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.

Solution: http://www.gwtproject.org/articles/using_gwt_with_hibernate.html: 1. write our own light weight DTO, separating from Entity bean. 2. use Dozer to generate DTO for each Entity bean. 3. use Gilead (hibernate4gwt) lib.

1 comment:

Web Design Company in Chennai said...

Nice! Really cool stuff and very inspiring.

 
Get This <