Mr Jedi
Mr Jedi

Reputation: 34715

Hibernate won't save particular object to db

I develop app in spring mvc, using hibernate.

I trying save 3 different objects (instances different classes) in db and hibernate saves only 2 of them. I using services, and daos with generic dao so adding to db is same for every object.

Here is code:

Models of 3 object Category, Product, CategoryProduct:

@Entity
@Table(name="CATEGORY")
public class Category implements Serializable{

    public static final String ID = "ID";

    public static final String FK_CATEGORY = "FK_CATEGORY";

    public static final String NAME = "NAME";

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column( name = Category.ID )
    private long id;

    @ManyToOne
    @JoinColumn( name = Category.FK_CATEGORY )
    private Category parentCategory;

    @Column( name = Category.NAME )
    private String name;
}

@Entity
@Table(name="PRODUCT")
public class Product implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    private long id;

    @Column(name="NAME")
    private String name;

    @Column(name="DESCRIPTION")
    private String description;

    @Column(name="PRICE")
    private double price;

    @Column(name="QUANTITY")
    private int quantityInMagazine;
}

@Entity
@Table(name="CATEGORY_PRODUCT")
public class CategoryProduct implements Serializable{

    @Id
    @ManyToOne
    @JoinColumn(name="FK_CATEGORY", referencedColumnName = "id")
    private Category category;

    @Id
    @ManyToOne
    @JoinColumn(name="FK_PRODUCT", referencedColumnName="id")
    private Product product;
}

This is my test:

@Test
    public void getProductByCategoryId()
    {
        Product beaf = new Product();
        beaf.setName("Beaf");
        beaf.setPrice((Double)3.40);
        beaf.setDescription("awsome beaf");
        beaf.setQuantityInMagazine(40);

        Product ham = new Product();

        productService.save(beaf);
        productService.save(ham);

        Category category = new Category();
        category.setName("newCategoryWithParent");

        Category parentCategory = categoryService.get(Long.valueOf(1));
        category.setCategory(parentCategory);

        categoryService.save(category);


        CategoryProduct categoryProduct= new CategoryProduct();

        categoryProduct.setProduct(beaf);
        categoryProduct.setCategory(category);

        CategoryProduct ct = (CategoryProduct) categoryProductService.save(categoryProduct);


        List<Product> productFromDB = productService.findByCategory(category.getId());
        assertEquals(productFromDB.size(), 1);
        assertEquals(productFromDB.get(0).getName(), ham.getName());
        assertEquals(productFromDB.get(0).getPrice(), ham.getPrice());
        assertEquals(productFromDB.get(0).getQuantityInMagazine(), ham.getQuantityInMagazine());

    }

This line:

categoryProductService.save(categoryProduct);

do nothing. Console don't show me error or sql statement. Just nothing. Same save work for others object but not for CategoryProduct. This is my Abstract Service:

public abstract class AbstractService<T> {

    private Class<T> type;

    /*public AbstractService(){
        Type t = getClass().getGenericSuperclass();
        ParameterizedType pt = (ParameterizedType) t;
        type = (Class) pt.getActualTypeArguments()[0];
    }*/

    @Transactional
    public Object save(final T t){
        return getDao().save(t);
    }

    @Transactional
    public void update(final T t){
        getDao().update(t);
    }

    @Transactional
    public void delete(final T t){
        getDao().delete(t);
    }

    @Transactional
    public IGenericDao getDao(){
        return null;
    }
}

and save method from generic dao:

@Override
public Object save(final T t) {
    Session session = getCurrentSession();
    return session.save(t);
}

Any ideas why hibernate won't save this particular object?

Upvotes: 0

Views: 1106

Answers (2)

jignasha
jignasha

Reputation: 73

I think, there is an issue with model implementation of CategoryProduct. I think you are trying to make Composite key using category and product.

So, you should be using @EmbeddedId instead of using @Id annotation.

You can use functionality "Create Entity from database" provided by netbeans to create perfect entity classes.

Thanks, Jignasha.

Upvotes: 0

Boyan
Boyan

Reputation: 599

I think hibernate is throwing a RuntimeException that you don't log and that's why your object is not persisted. Regarding the possible problem - as jignasha said you cannot define a composite PK this way. You have to either define the composite key correctly like:

@Entity
public class CategoryProduct  implements Serializable {
    @EmbeddedId CategoryProductId id;
    //...
}

@Embeddable
Class CategoryProductId implements Serializable {
    long productId;
    long categoryId;
}

Or define a new PK for CategoryProduct:

@Entity
public class CategoryProduct  implements Serializable {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private long id;
      //...
}

Also you must have the following thing in mind when you define a PK (directly taken from javax.persistence.Id JavaDoc):

The field or property to which the Id annotation is applied should be one of the following types: any Java primitive type; any primitive wrapper type; String; java.util.Date; java.sql.Date; java.math.BigDecimal; java.math.BigInteger.

I have a couple of more comments, which are not relevant to your current problem, you may consider:

  • You can put @Transactional at class level and it will be applied for all public methods in the class.
  • There's a project named Spring Data which you can use. It gives you CRUD + several other goodies by just defining an repository interface to your table(s). This way it is not needed to write the boilerplate, error prone code, but rather delegate this to the framework.

Upvotes: 1

Related Questions