Hi, I'm new to Hibernate and I have a problem that I've been breaking my head over:
I have a Reservation object, which should have a list of Service objects. But a Service also has an amount, for example: a Service is for example a desktop computer which you can order 10 of, so you also need an amount field somewhere. I think I know what I wanna end up with, which a table with the following columns:
reservations_r_id - The Reservation
service_s_id - The Service
amount - Amount of a Service in the Reservation
So I know what I should end up with, but I have no clue how to achieve that table using Java objects. I was told to use an Embeddable object as an EmbeddedId. I've implemented it like this:
The Reservation object:
Code:
@Entity
@Table(name = "reservations")
public class Reservation
{
..
@OneToMany
private List<ReservationService> services;
..
}
The Embeddable object I made for the shared PK:
Code:
@Embeddable
public class ReservationServicePk implements Serializable
{
@OneToOne
private Reservation reservation;
@OneToOne
private Service service;
public Reservation getReservation()
{
return reservation;
}
public void setReservation(Reservation reservation)
{
this.reservation = reservation;
}
public Service getService()
{
return service;
}
public void setService(Service service)
{
this.service = service;
}
@Override
public boolean equals(Object obj)
{
return super.equals(obj);
}
}
The ReservationService object I made that uses the ReservationServicePk as embedded id:
Code:
@Entity
@Table
public class ReservationService implements Serializable
{
@EmbeddedId
private ReservationServicePk reservationservicepk = new ReservationServicePk();
@Column(name = "rs_amount")
private int amount;
public Reservation getReservation()
{
return reservationservicepk.getReservation();
}
public Service getService()
{
return reservationservicepk.getService();
}
public void setReservation(Reservation reservation)
{
reservationservicepk.setReservation(reservation);
}
public void setService(Service service)
{
reservationservicepk.setService(service);
}
public int getAmount()
{
return amount;
}
public void setAmount(int amount)
{
this.amount = amount;
}
}
I use the objects in my code like this:
Code:
List list = new ArrayList<ReservationService>();
ReservationService service = new ReservationService();
service.setReservation(reservationobject); service.setService(serviceobject);
list.add(s);
reservationobject.setFlexservices(list);
However, when I try to save the Reservation object (which now has a list of ReservationServices) I get this exception (and the first bit is the last thing Hibernate throws in the console):
Code:
Saving object: class gfs.beans.Reservation
Hibernate: insert into reservations (r_active, r_added, r_checkedIn, client_c_id, r_endtime, floor_f_id, location_l_id, r_people, r_workplaces, r_processed, product_p_id, r_room, r_type, r_starttime, r_user_notes) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: select currval('reservations_r_id_seq')
Hibernate: insert into reservations_ReservationService (reservations_r_id, flexservices_reservation_r_id, flexservices_service_s_id) values (?, ?, ?)
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:171)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at gfs.hibernate.HibernateUtil.save(HibernateUtil.java:82)
at gfs.db.DBReservation.addReservation(DBReservation.java:61)
at gfs.gui.ReservationAddPlanboard.receiveConfirmation(ReservationAddPlanboard.java:190)
at gfs.gui.components.MessageBar$ButtonListener.actionPerformed(MessageBar.java:268)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.sql.BatchUpdateException: Batch entry 0 insert into reservations_ReservationService (reservations_r_id, flexservices_reservation_r_id, flexservices_service_s_id) values (13, 13, 2) was aborted. Call getNextException to see the cause.
at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2534)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1317)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:350)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2596)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
... 36 more
The second table it inserts into (reservations_reservationservice) is a very messed up table, looking like this:
reservations_r_id integer NOT NULL,
services_reservation_r_id integer NOT NULL,
services_service_s_id integer NOT NULL,
It does not have a primary key. So I don't know why Hibernate creates a table like that.
I have no idea what I'm doing wrong and neither do people around me who only have slightly more experience with this. I hope someone of you does. Sorry for the lenghty post. If there's anything else you need to know, please post it.