views:

1393

answers:

4

I'm using JPA (Hibernate implementation) to save objects to the database. Selecting works fine, but for some reason, saving doesn't work. I don't get any errors, but the database doesn't get changed either. This goes for both new entities and existing ones.

 EPayment pay = new EPayment();
 pay.setAmount(payment.getAmount());
 ...
 pay.setUserByToUserId(receiver);
 CompayDAO.get().save(pay);

CompayDAO.save()

public void save(Object ent) {
 System.out.println("Persisting: " + ent + " using " + this);
 this.em.persist(ent);
}

Console output:

Opening DOA nl.compay.entities.CompayDAO@b124fa
Persisting: nl.compay.entities.EUser@1e2fe5d using nl.compay.entities.CompayDAO@b124fa
Persisting: nl.compay.entities.EUser@30b601 using nl.compay.entities.CompayDAO@b124fa
Persisting: nl.compay.entities.EPayment@ed3b53 using nl.compay.entities.CompayDAO@b124fa
Closing DOA nl.compay.entities.CompayDAO@b124fa

EPayment

package nl.compay.entities;

// Generated 21-mei-2009 12:27:07 by Hibernate Tools 3.2.2.GA

import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
 * Payment generated by hbm2java
 */
@Entity
@Table(name = "payment", catalog = "compay")
public class EPayment implements java.io.Serializable {

 private static final long serialVersionUID = -2578493336948256566L;

 private Integer id;
 private EUser userByToUserId;
 private EUser userByFromUserId;
 private String description;
 private float amount;
 private String method;
 private Date paydate;

 public EPayment() {
 }

 public EPayment(EUser userByToUserId, EUser userByFromUserId, float amount,
   Date paydate) {
  this.userByToUserId = userByToUserId;
  this.userByFromUserId = userByFromUserId;
  this.amount = amount;
  this.paydate = paydate;
 }

 public EPayment(EUser userByToUserId, EUser userByFromUserId,
   String description, float amount, String method, Date paydate) {
  this.userByToUserId = userByToUserId;
  this.userByFromUserId = userByFromUserId;
  this.description = description;
  this.amount = amount;
  this.method = method;
  this.paydate = paydate;
 }

 @Id
 @GeneratedValue(strategy = IDENTITY)
 @Column(name = "id", unique = true, nullable = false)
 public Integer getId() {
  return this.id;
 }

 public void setId(Integer id) {
  this.id = id;
 }

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "to_user_id", nullable = false)
 public EUser getUserByToUserId() {
  return this.userByToUserId;
 }

 public void setUserByToUserId(EUser userByToUserId) {
  this.userByToUserId = userByToUserId;
 }

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "from_user_id", nullable = false)
 public EUser getUserByFromUserId() {
  return this.userByFromUserId;
 }

 public void setUserByFromUserId(EUser userByFromUserId) {
  this.userByFromUserId = userByFromUserId;
 }

 @Column(name = "description", length = 1024)
 public String getDescription() {
  return this.description;
 }

 public void setDescription(String description) {
  this.description = description;
 }

 @Column(name = "amount", nullable = false, precision = 8)
 public float getAmount() {
  return this.amount;
 }

 public void setAmount(float amount) {
  this.amount = amount;
 }

 @Column(name = "method", length = 50)
 public String getMethod() {
  return this.method;
 }

 public void setMethod(String method) {
  this.method = method;
 }

 @Temporal(TemporalType.TIMESTAMP)
 @Column(name = "paydate", nullable = false, length = 0)
 public Date getPaydate() {
  return this.paydate;
 }

 public void setPaydate(Date paydate) {
  this.paydate = paydate;
 }

}
+1  A: 

The program doesn't have to sync with the database right away, have you tried this.em.flush(); somewhere?

Johan
No, but I do em.close(). Does that imply a flush too, or does it mean I'm throwing stuff away?
Bart van Heukelom
em.close() doesn't automatically flush things to the database. Better to use transactions (I agree with rudolfson) or use em.flush()
Johan
+1  A: 

As Sherkaner mentioned, a save doesn't result in an INSERT or UPDATE directly. You have to flush the session or - better in my opinion - close the unit of work / commit the transaction. You do have transactions?

rudolfson
See my comment @Sherkaner
Bart van Heukelom
Well, I'm not a JPA expert (just using Hibernate + JPA Annotations + Spring), but according to the EntityManager's javadoc of the close() method, the transaction is still alive.See http://java.sun.com/javaee/5/docs/api/javax/persistence/EntityManager.html#close().So you still have to commit the transaction (e.g. by calling em.getTransaction().commit(), but I would suggest some declarative transaction management.
rudolfson
A: 

Don't think this as bug in Hibernate implementation.This is desired behavior,you would like to have minimum communication with database so Hibernate(or any good ORM framework) will consolidate all your changes and will flush your changes in one go.

Khangharoth
I never did. It's a bug with me ;)
Bart van Heukelom
A: 

use @Transactional on your method.....

@Transactional public void save(Object ent){ ..... ..... }

Ansh jain