Hello,
I currently evaluating Smartgwt enterprise edition 3.1d (2012/10/11) and get the following error:
It seems that smartgwt is trying to serialize some proxies generated by hiberanet (4.1.7.Final)
Here is the code I used:
To reproduce do the follwoing:
1. add + save an order
2. add + save two items (for the Order) (here the DMI works as expected)
3. modify an item and save it.
btw.: Why is SmartGwt trying to access the items of the order, I configured dropExtraFields="true" in the order.ds.xml
I currently evaluating Smartgwt enterprise edition 3.1d (2012/10/11) and get the following error:
Code:
=== 2012-10-14 11:24:48,097 [70-4] WARN JSTranslater - org.hibernate.internal.SessionFactoryImpl contains a (potentially indirect) looping reference to itself. Returning null for recursed value. === 2012-10-14 11:24:48,131 [70-4] WARN HibernateTransaction - Attempted to commit inactive transaction === 2012-10-14 11:24:48,133 [70-4] ERROR IDACall - Error executing operation: item_update com.isomorphic.js.UnconvertableException: com.isomorphic.js.UnconvertableException: com.isomorphic.js.UnconvertableException: com.isomorphic.js.UnconvertableException: java.lang.UnsupportedOperationException at org.hibernate.internal.util.collections.IdentityMap.keySet(IdentityMap.java:140) at com.isomorphic.js.JSTranslater.convertMap(JSTranslater.java:1013) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:661) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:599) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:590) at com.isomorphic.js.JSTranslater.convertMap(JSTranslater.java:1053) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:711) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:599) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:590) at com.isomorphic.js.JSTranslater.convertMap(JSTranslater.java:1053) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:711) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:599) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:590) at com.isomorphic.js.JSTranslater.convertMap(JSTranslater.java:1053) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:711) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:599) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:590) at com.isomorphic.js.JSTranslater.convertMap(JSTranslater.java:1053) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:711) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:599) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:590) at com.isomorphic.js.JSTranslater.convertMap(JSTranslater.java:1053) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:661) at com.isomorphic.js.JSTranslater.convertIterator(JSTranslater.java:1215) at com.isomorphic.js.JSTranslater.convertCollection(JSTranslater.java:1166) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:663) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:599) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:590) at com.isomorphic.js.JSTranslater.convertMap(JSTranslater.java:1053) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:661) at com.isomorphic.js.JSTranslater.convertIterator(JSTranslater.java:1215) at com.isomorphic.js.JSTranslater.convertCollection(JSTranslater.java:1166) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:663) at com.isomorphic.js.JSTranslater.convert(JSTranslater.java:599) at com.isomorphic.js.JSTranslater.toJS(JSTranslater.java:561) at com.isomorphic.rpc.RPCManager.completeResponse(RPCManager.java:1316) at com.isomorphic.rpc.RPCManager.send(RPCManager.java:586) at com.isomorphic.servlet.IDACall.processRPCTransaction(IDACall.java:173) at com.isomorphic.servlet.IDACall.processRequest(IDACall.java:138) at com.isomorphic.servlet.IDACall.doPost(IDACall.java:74) at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:152) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:861) at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:579) at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1584) at java.lang.Thread.run(Thread.java:662)
Here is the code I used:
Code:
package test.server; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.OneToMany; import java.util.Collection; @Entity public class OrderEntity { @Id private long orderNumber; private double total; @OneToMany(mappedBy = "theOrder", cascade = CascadeType.ALL) private Collection<ItemEntity> items; /* getter + setter */ }
Code:
package test.server; import org.hibernate.annotations.GenericGenerator; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToOne; @Entity public class ItemEntity { @Id @GeneratedValue(generator = "uuid") @GenericGenerator(name = "uuid", strategy = "uuid2") private String id; private String name; private int quantity; private double price; @ManyToOne(fetch = FetchType.LAZY) private OrderEntity theOrder; /* getter + setter */ }
Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <DataSource ID="order" serverType="hibernate" dropExtraFields="true" beanClassName="test.server.OrderEntity"> <fields> <field name="orderNumber" type="integer" primaryKey="true"/> <field name="total" type="float"/> </fields> </DataSource>
Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <DataSource ID="item" serverType="hibernate" dropExtraFields="true" beanClassName="test.server.ItemEntity"> <fields> <field name="id" type="text" primaryKey="true" autoGenerated="true" hidden="true"/> <field name="name" type="text"/> <field name="quantity" type="integer"/> <field name="price" type="float"/> <field name="theOrder" canEdit="true" foreignKey="order.orderNumber"/> </fields> <serverObject className="test.server.DMITest" lookupStyle="new"/> </DataSource>
Code:
package test.server; import com.isomorphic.datasource.DSRequest; import com.isomorphic.datasource.DSResponse; import com.isomorphic.datasource.DataSource; import com.isomorphic.hibernate.HibernateTransaction; import org.hibernate.Session; import org.hibernate.Transaction; public class DMITest { public DSResponse update(DSRequest request) throws Exception { return handleItem(request); } public DSResponse add(DSRequest request) throws Exception { return handleItem(request); } private DSResponse handleItem(DSRequest request) throws Exception { DSResponse response = request.execute(); ItemEntity item = (ItemEntity) response.getData(); double total = 0; OrderEntity order = item.getTheOrder(); if (!order.getItems().contains(item)){ order.getItems().add(item); } for (ItemEntity itemEntity : order.getItems()) { total += itemEntity.getPrice() * itemEntity.getQuantity(); } order.setTotal(total); // don't use this http://forums.smartclient.com/showthread.php?t=23970 Session session = HibernateTransaction.getTransactionSession((Transaction) request.getDataSource().getTransactionObject(request)); session.update(order); DSResponse updateResponse = new DSResponse(DataSource.forName("order", null), order); updateResponse.setOperationType(DataSource.OP_UPDATE); response.addRelatedUpdate(updateResponse); return response; } }
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 orderDs = DataSource.get("order"); final ListGrid orderGrid = new ListGrid(); orderGrid.setDataSource(orderDs); initGrid(orderGrid); final ListGrid itemGrid = new ListGrid(); itemGrid.setDataSource(DataSource.get("item")); SelectItem selectItem = new SelectItem("theOrder"); selectItem.setOptionDataSource(orderDs); ListGridField infoListGridField = new ListGridField("theOrder"); infoListGridField.setEditorType(selectItem); itemGrid.setFields(infoListGridField); initGrid(itemGrid); HLayout mainLayout = new HLayout(); mainLayout.setWidth100(); mainLayout.setHeight100(); mainLayout.addMember(orderGrid); mainLayout.addMember(itemGrid); 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); } }
1. add + save an order
2. add + save two items (for the Order) (here the DMI works as expected)
3. modify an item and save it.
btw.: Why is SmartGwt trying to access the items of the order, I configured dropExtraFields="true" in the order.ds.xml
Comment