我有两个实体,产品和购买,他们有很多关系。 因此,我们创建了第三个表purchaseProduct。上述每个参与者的DDL是:
CREATE TABLE purchase
(
idpurchase serial NOT NULL,
code character varying(50),
date timestamp without time zone,
totalht double precision,
tva double precision,
totalttc double precision,
CONSTRAINT purchase_pkey PRIMARY KEY (idpurchase)
)
CREATE TABLE product
(
idproduct serial NOT NULL,
namear character varying(50),
namefr character varying(50),
preference character varying(50),
qtystart double precision,
qtyinhand double precision,
sellprice double precision,
purchaseprice double precision,
taxe double precision,
CONSTRAINT product_pkey PRIMARY KEY (idproduct)
)
CREATE TABLE purchaseproduct
(
idpurchase integer NOT NULL,
idproduct integer NOT NULL,
qty double precision,
price double precision,
CONSTRAINT purchaseproduct_pkey PRIMARY KEY (idpurchase, idproduct),
CONSTRAINT purchaseproduct_idproduct_fkey FOREIGN KEY (idproduct)
REFERENCES product (idproduct) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT purchaseproduct_idpurchase_fkey FOREIGN KEY (idpurchase)
REFERENCES purchase (idpurchase) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
没有getter和setter的相应类是:
@Entity
@Table(name = "Product")
@Access(AccessType.PROPERTY)
public class Product {
private LongProperty idProduct;
private StringProperty nameAr;
private StringProperty nameFr;
private StringProperty preference;
private DoubleProperty qtyStart;
private DoubleProperty qtyInHand;
private DoubleProperty sellPrice;
private DoubleProperty purchasePrice;
private DoubleProperty taxe;
private Set<LineCommand> items = new HashSet<LineCommand>();
@OneToMany(mappedBy = "product", cascade =CascadeType.ALL)
public Set<LineCommand> getItems() {
return items;
}
}
@Entity
@Table(name = "purchase")
@Access(AccessType.PROPERTY)
public class Purchase {
private LongProperty idPurchase;
private StringProperty codePurchase;
private ObjectProperty<Timestamp> datePurchase;
private DoubleProperty totalHt;
private DoubleProperty tva;
private DoubleProperty totalTTC;
private Set<LineCommand> lineItems = new HashSet<LineCommand>(0);
@OneToMany(mappedBy = "purchase",
cascade = CascadeType.ALL)
public Set<LineCommand> getLineItems() {
return this.lineItems;
}
}
@Entity
@Table(name = "purchaseProduct")
@Access(AccessType.PROPERTY)
@IdClass(LineCommandId.class)
public class LineCommand implements Serializable {
private Product product;
private Purchase purchase;
public void setPurchase(Purchase purchase) {
this.purchase = purchase;
}
@Id
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "idpurchase", updatable = false, insertable = false, referencedColumnName = "idpurchase")
public Purchase getPurchase() {
return purchase;
}
@Id
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "idproduct", updatable = false, insertable = false, referencedColumnName = "idproduct")
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
private DoubleProperty sellPrice = new SimpleDoubleProperty();
private DoubleProperty qty = new SimpleDoubleProperty();
@Column(name = "price")
public double getSellPrice() {
return sellPrice.get();
}
public DoubleProperty sellPriceProperty() {
return sellPrice;
}
public void setSellPrice(double sellPrice) {
this.sellPrice.set(sellPrice);
}
@Column(name = "qty")
public double getQty() {
return qty.get();
}
public DoubleProperty qtyProperty() {
return qty;
}
public void setQty(double qty) {
this.qty.set(qty);
}
}
最后是coumbound关键课:
public class LineCommandId implements Serializable {
private Product product;
private Purchase purchase;
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public Purchase getPurchase() {
return purchase;
}
public void setPurchase(Purchase purchase) {
this.purchase = purchase;
}
}
经过测试:
@Test
public void testAddPurchase() {
Purchase purchase = new Purchase();
Product product = new Product();
LineCommand lineCommand = new LineCommand();
PurchaseDAO dao = new PurchaseDAO();
purchase.setCodePurchase("First Purchase");
purchase.setTotalHt(200000);
purchase.getLineItems().add(lineCommand);
product.setNameFr("First Product");
product.setQtyStart(30);
product.getItems().add(lineCommand);
lineCommand.setPurchase(purchase);
lineCommand.setProduct(product);
Assert.assertTrue(dao.create(purchase));
}
我收到此错误:
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: model.Product
at org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:279)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:455)
at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:153)
at org.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:343)
at org.hibernate.persister.entity.AbstractEntityPersister.getDatabaseSnapshot(AbstractEntityPersister.java:1280)
at org.hibernate.engine.internal.StatefulPersistenceContext.getDatabaseSnapshot(StatefulPersistenceContext.java:314)
at org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:238)
at org.hibernate.event.internal.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:510)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:83)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:648)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:640)
at org.hibernate.engine.spi.CascadingActions$5.cascade(CascadingActions.java:218)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:398)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:162)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:431)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:363)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:162)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:111)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:456)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:278)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:178)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:679)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:671)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:666)
at dao.PurchaseDAO.create(PurchaseDAO.java:49)
at dao.PurchaseDAOTest.testAddPurchase(PurchaseDAOTest.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:86)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertTrue(Assert.java:52)
at dao.PurchaseDAOTest.testAddPurchase(PurchaseDAOTest.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
答案 0 :(得分:0)
您是否尝试过向您的实体添加注释:cascade = CascadeType.ALL? 它将确保在保存主对象时保存集合项。
答案 1 :(得分:0)
您应首先将一些dao.create调用到您的产品