gpt4 book ai didi

java - Hibernate 不会将特定对象保存到数据库

转载 作者:行者123 更新时间:2023-12-01 13:20:47 25 4
gpt4 key购买 nike

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

我尝试在数据库中保存 3 个不同的对象(实例不同的类),而 hibernate 仅保存其中的 2 个。我使用服务,以及具有通用 dao 的 daos,因此添加到数据库对于每个对象都是相同的。

这里是代码:

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 不会保存这个特定的对象吗?

最佳答案

我认为 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):

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.

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

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

关于java - Hibernate 不会将特定对象保存到数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22038786/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com