Reputation: 34715
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
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
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:
Upvotes: 1