Hello,
there seems to be a bug in the Hibernate Datsource if the field name of an entity is equals to a field name of a related entity. (I currently evaluating the 3.1d enterprise edition (2012/10/04).
the code is like this:
Now you create 2 sites and one ShippingMethod. After this you change the Site of the ShippingMethod (update). Now you get this warning:
The data in the example is updated correctly, but under certain circumstances, which I could not yet identify, you get the following warning:
in this case no update is commited to the Database. I could extract the following StackTrace for this Exception:
Stepping throught the stack shows that the HibernateDatasource is trying to set a parameter of type test.server.Translatable for the query
This seems to be a bug.
there seems to be a bug in the Hibernate Datsource if the field name of an entity is equals to a field name of a related entity. (I currently evaluating the 3.1d enterprise edition (2012/10/04).
the code is like this:
Code:
@Entity public class ShippingMethod implements Serializable { @Id private String id; @AttributeOverride(name = "defaultValue", column = @Column(name = "name", length = 50)) @Embedded private Translatable name; @ManyToOne(fetch = FetchType.LAZY, optional = false) private Site site; /* getter + setter */ }
Code:
package test.server; import javax.persistence.AttributeOverride; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.ManyToOne; import java.io.Serializable; @Entity public class ShippingMethod implements Serializable { @Id private String id; @AttributeOverride(name = "defaultValue", column = @Column(name = "name", length = 50)) @Embedded private Translatable name; @ManyToOne(fetch = FetchType.LAZY, optional = false) private Site site; /* getter + setter */ }
Code:
package test.server; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.OneToMany; import java.io.Serializable; import java.util.Collection; @Entity public class Site implements Serializable { @Id private String name; @OneToMany(mappedBy = "site", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private Collection<ShippingMethod> shippingMethods; /* getter + setter */ }
Code:
package test.server; import javax.persistence.Access; import javax.persistence.AccessType; import javax.persistence.Embeddable; @Embeddable @Access(AccessType.FIELD) public class Translatable { private String defaultValue; /* getter + setter */ }
Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <DataSource ID="shippingMethod" serverType="hibernate" dropExtraFields="true" beanClassName="test.server.ShippingMethod"> <fields> <field name="id" type="text" primaryKey="true"/> <field name="name" type="text" valueXPath="/name/defaultValue"/> <field name="site" required="true" canEdit="true" foreignKey="site.name" displayField="site_name"/> <field name="site_name" type="text" valueXPath="site/name" canEdit="false" canSave="false" hidden="true"/> </fields> </DataSource>
Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <DataSource ID="site" serverType="hibernate" dropExtraFields="true" beanClassName="test.server.Site"> <fields> <field name="name" type="text" primaryKey="true"/> </fields> </DataSource>
Code:
package test.client; import com.google.gwt.core.client.EntryPoint; import com.smartgwt.client.data.DataSource; import com.smartgwt.client.types.ListGridComponent; import com.smartgwt.client.widgets.events.ClickEvent; import com.smartgwt.client.widgets.events.ClickHandler; import com.smartgwt.client.widgets.form.fields.SelectItem; import com.smartgwt.client.widgets.grid.ListGrid; import com.smartgwt.client.widgets.grid.ListGridField; import com.smartgwt.client.widgets.layout.HLayout; import com.smartgwt.client.widgets.toolbar.ToolStrip; import com.smartgwt.client.widgets.toolbar.ToolStripButton; public class Entry implements EntryPoint { public void onModuleLoad() { DataSource siteDs = DataSource.get("site"); final ListGrid siteGrid = new ListGrid(); siteGrid.setDataSource(siteDs); initGrid(siteGrid); final ListGrid shippingMethodGrid = new ListGrid(); shippingMethodGrid.setDataSource(DataSource.get("shippingMethod")); SelectItem selectItem = new SelectItem("site"); selectItem.setOptionDataSource(siteDs); selectItem.setDisplayField("name"); selectItem.setValueField(siteDs.getPrimaryKeyFieldName()); ListGridField infoListGridField = new ListGridField("site"); infoListGridField.setEditorType(selectItem); shippingMethodGrid.setFields(infoListGridField); initGrid(shippingMethodGrid); HLayout mainLayout = new HLayout(); mainLayout.setWidth100(); mainLayout.setHeight100(); mainLayout.addMember(siteGrid); mainLayout.addMember(shippingMethodGrid); mainLayout.draw(); } private void initGrid(final ListGrid grid) { grid.setAutoFetchData(true); grid.setAutoSaveEdits(false); grid.setCanEdit(true); grid.setUseAllDataSourceFields(true); ToolStrip strip = new ToolStrip(); ToolStripButton save = new ToolStripButton("save"); save.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent clickEvent) { grid.saveAllEdits(); } }); strip.addButton(save); ToolStripButton add = new ToolStripButton("add"); add.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent clickEvent) { grid.startEditingNew(); } }); strip.addButton(add); grid.setGridComponents(ListGridComponent.HEADER, ListGridComponent.BODY, strip); } }
Code:
=== 2012-10-10 01:47:04,919 [70-1] WARN HibernateDataSource - [builtinApplication.shippingMethod_update] java.lang.IllegalArgumentException: Can't convert value of type java.lang.String to target type test.server.Translatable
Code:
=!= 2012-10-10 01:34:36,258 [sor3] WARN DataSource - [builtinApplication.shippingMethod_update] Couldn't set property 'site' for datasource 'shippingMethod'. Actual error: java.lang.ClassCastException: test.servern.Translatable cannot be cast to java.lang.String
Code:
java.lang.ClassCastException: test.server.Translatable cannot be cast to java.lang.String at org.hibernate.type.descriptor.java.StringTypeDescriptor.unwrap(StringTypeDescriptor.java:38) at org.hibernate.type.descriptor.sql.VarcharTypeDescriptor$1.doBind(VarcharTypeDescriptor.java:57) at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:92) at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:305) at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:300) at org.hibernate.param.NamedParameterSpecification.bind(NamedParameterSpecification.java:66) at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:588) at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1736) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1697) at org.hibernate.loader.Loader.doQuery(Loader.java:832) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:293) at org.hibernate.loader.Loader.doList(Loader.java:2382) at org.hibernate.loader.Loader.doList(Loader.java:2368) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2198) at org.hibernate.loader.Loader.list(Loader.java:2193) at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:470) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355) at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1244) at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101) at com.isomorphic.hibernate.HibernateDataSource.setRelationFieldValue(HibernateDataSource.java:5945) at com.isomorphic.datasource.DataSource.setProperties(DataSource.java:1629) at com.isomorphic.datasource.DataSource.setProperties(DataSource.java:1582) at com.isomorphic.hibernate.HibernateDataSource.processRequest(HibernateDataSource.java:1433) at com.isomorphic.hibernate.HibernateDataSource.executeUpdate(HibernateDataSource.java:805) at com.isomorphic.datasource.DataSource.execute(DataSource.java:1384) at com.isomorphic.application.AppBase.executeDefaultDSOperation(AppBase.java:726) at com.isomorphic.application.AppBase.executeAppOperation(AppBase.java:658) at com.isomorphic.application.AppBase.execute(AppBase.java:491) at com.isomorphic.datasource.DSRequest.execute(DSRequest.java:2011)
Code:
select __Site from test.server.Site __Site where __Site.name = :p0
Comment