Hi All !
I'm struggling with a persistence problem since 3 days. I can persist normal bean classes to the database, but a
(parent-child relation) many-to-one one-to-many mapping doesn't work.
I have tried many things, read the documentation and examples, but the problem is still there. I have to classes called
Quote:
Order
and
Quote:
OrderPosition
.
I have defined two mapping files
Quote:
Order.hbm.xml
and
Quote:
OrderPosition.hbm.xml
.
I try in a
servlet to insert a order into the database, which causes an exception. See below the defitions of the classes and mapping files and the error log.
I'm using
Hibernate 3.2, hsqldb 1.8.0.7 under eclipse 3.2 on windows.
Code:
<hibernate-mapping>
<class name="model.OrderPosition" table="ORDERPOSITION">
<id name="id" type="java.lang.Long">
<column name="ORDERPOSITION_ID" />
<generator class="native"></generator>
</id>
<property name="number" type="java.lang.String">
<column name="number" not-null="true" unique="true" />
</property>
<property name="note" type="java.lang.String">
<column name="note" />
</property>
<property name="quantity" type="java.lang.Long">
<column name="quantity" />
</property>
<property name="price" type="java.lang.Double">
<column name="price" />
</property>
<many-to-one name="order" class="model.Order">
<column name="ORDER_ID" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
Code:
<hibernate-mapping>
<class name="model.Order" table="ORDER">
<id name="id" type="java.lang.Long">
<column name="ORDER_ID" />
<generator class="native"></generator>
</id>
<property name="number" type="java.lang.String">
<column name="number" not-null="true" unique="true" />
</property>
<property name="orderDate" type="timestamp">
<column name="ORDER_DATE" />
</property>
<set name="positions" inverse="true" cascade="all">
<key>
<column name="ORDER_ID" />
</key>
<one-to-many class="model.OrderPosition" />
</set>
</class>
</hibernate-mapping>
Code:
public class OrderPosition {
private Long id;
private String number;
private String note;
private Long quantity;
private Double price;
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Long getQuantity() {
return quantity;
}
public void setQuantity(Long quantity) {
this.quantity = quantity;
}
}
Code:
public class Order {
private Long id;
private String number = null;
private Set positions = new HashSet();
private Date orderDate = null;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public void addPosition(OrderPosition pos) {
pos.setOrder(this);
positions.add(pos);
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Set getPositions() {
return positions;
}
public void setPositions(Set positions) {
this.positions = positions;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
}
Code:
public class OrderServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("action");
if (action != null && action.trim().length() > 0) {
Session hSession = HibernateUtil.getSession();
try {
hSession.beginTransaction();
action = action.trim();
if (action.equalsIgnoreCase("insert")) {
saveOrder(hSession, request);
} else if (action.equalsIgnoreCase("update")) {
updateOrder(hSession, request);
}
hSession.getTransaction().commit();
// response
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
response.getWriter().write(
"Order has been inserted successfully.");
} catch (Exception exc) {
System.out.println("Error: " + exc.getMessage());
exc.printStackTrace();
Transaction tx = hSession.getTransaction();
if (tx != null)
tx.rollback();
throw new ServletException(exc);
}
}
}
private void saveOrder(Session session, HttpServletRequest request)
throws Exception {
try {
Order order = new Order();
order.setNumber("A1");
order.setOrderDate(new Date());
// Code to retrieve postions from request
ArrayList positions = ...
for (int i = 0; i < positions.length(); i++) {
OrderPosition pos = new OrderPosition();
// Code to init position
// ...
// position is initialized
order.addPosition(pos);
}
session.save(order);
session.flush();
} catch (Exception exc) {
System.out.println("Exception in saveOrder(): "
+ exc.getMessage());
throw exc;
}
}
}
Finally the occured exceptions:
Code:
03:14:14,981 ERROR [OrderServlet]:253 - Servlet.service() for servlet OrderServlet threw exception
org.hibernate.exception.SQLGrammarException: could not insert: [model.Order]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:40)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2108)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2588)
at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:48)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:290)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:180)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:108)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:519)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:301)
at $Proxy0.save(Unknown Source)
at controller.OrderServlet.saveOrder(OrderServlet.java:99)
at controller.OrderServlet.doPost(OrderServlet.java:48)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)
Caused by: java.sql.SQLException: Unexpected token: ORDER in statement [insert into ORDER (ORDER_ID, number, ORDER_DATE) values (null, ?, ?)]
at org.hsqldb.jdbc.Util.throwError(Unknown Source)
at org.hsqldb.jdbc.jdbcPreparedStatement.<init>(Unknown Source)
at org.hsqldb.jdbc.jdbcConnection.prepareStatement(Unknown Source)
at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:497)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:94)
at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:30)
... 39 more
Thanks for any suggestions.