Hibernate不会将特定对象保存到db

时间:2014-02-26 10:38:02

标签: java database spring hibernate

我使用hibernate在spring mvc中开发应用程序。

我尝试在db中保存3个不同的对象(实例不同的类),而hibernate只保存其中的2个。我使用服务和带有泛型dao的dao,因此对每个对象添加到db都是相同的。

这是代码:

3个对象的模型类别,产品,类别产品:

@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;
}

这是我的测试:

@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());

    }

这一行:

categoryProductService.save(categoryProduct);

什么都不做。控制台不显示错误或sql语句。根本不值一提。其他对象的保存工作相同,但不适用于CategoryProduct。这是我的抽象服务:

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;
    }
}

并保存来自泛型dao的方法:

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

为什么hibernate不会保存这个特定对象?

2 个答案:

答案 0 :(得分:1)

我认为hibernate会抛出一个你没有记录的RuntimeException,这就是为什么你的对象没有被持久化的原因。 关于可能的问题 - 正如jignasha所说,你无法用这种方式定义复合PK。您必须正确定义组合键,如:

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

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

或者为CategoryProduct定义新的PK:

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

当您定义PK(直接取自javax.persistence.Id JavaDoc)时,您必须记住以下事项:

  

应用Id注释的字段或属性应该是   以下类型之一:任何Java基元类型;任何原始的   包装类型;串; java.util.Date; java.sql.Date;   java.math.BigDecimal的; java.math.BigInteger中。

我还有一些评论,这些评论与您当前的问题无关,您可以考虑:

  • 您可以将@Transactional放在类级别,它将应用于类中的所有公共方法。
  • 您可以使用名为Spring Data的项目。它通过定义表的存储库接口为您提供CRUD +其他几个好东西。这样就不需要编写样板,容易出错的代码,而是将其委托给框架。

答案 1 :(得分:0)

我认为,CategoryProduct的模型实施存在问题。我想您正在尝试使用类别和产品制作复合键。

因此,您应该使用@EmbeddedId而不是@Id注释。

您可以使用功能&#34; Create Entity from database&#34;由netbeans提供,以创建完美的实体类。

谢谢, Jignasha。