gpt4 book ai didi

java - Hibernate 与额外列的多对多关系

转载 作者:行者123 更新时间:2023-12-01 10:30:51 24 4
gpt4 key购买 nike

我在使用 JAVA 和 HIBERNATE 进行多对多关系映射时遇到问题我有 table 购买>--------------------------------<产品,所以我们得到另一张 table 购买产品,这是 DDL

    CREATE TABLE product (
idProduct serial primary key,
nameAr varchar(50),
nameFr varchar(50),
preference varchar(50),
qtyStart double PRECISION,
qtyInHand double PRECISION,
sellPrice double PRECISION ,
purchasePrice double PRECISION,
taxe double PRECISION
);


CREATE TABLE purchase (
idPurchase serial primary key,
code varchar(50) ,
date timestamp ,
totalHt double PRECISION,
tva double PRECISION,
totalTTC double PRECISION
);


CREATE TABLE purchaseProduct (
idPurchase integer,
idProduct integer,
qty double PRECISION,
price double PRECISION,
primary key(idPurchase,idProduct),
foreign key(idPurchase) references purchase(idPurchase),
foreign key(idProduct) references product(idProduct)
);

这是我的 hibernate.cfg.xml 配置:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<!-- Database connection settings -->
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="connection.url">jdbc:postgresql://localhost:5432/testInventory</property>
<property name="connection.username">postgres</property>
<property name="connection.password">myPassword</property>


<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.PostgreSQL82Dialect</property>

<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>

<mapping class="model.Product"/>
<mapping class="model.Purchase"/>
<mapping class="model.LineCommand"/>

</session-factory>

</hibernate-configuration>

我采用这种方法来建模多对多关系:

产品映射

@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> lineItems = new HashSet<LineCommand>(0);


public void setIdProduct(long idProduct) {
this.idProduct.set(idProduct);
}


public Product() {
idProduct = new SimpleLongProperty();
nameAr = new SimpleStringProperty();
nameFr = new SimpleStringProperty();
preference = new SimpleStringProperty();
qtyStart = new SimpleDoubleProperty();
qtyInHand = new SimpleDoubleProperty();
sellPrice = new SimpleDoubleProperty();
purchasePrice = new SimpleDoubleProperty();
taxe = new SimpleDoubleProperty();
}

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "product_seq_gen")
@SequenceGenerator(name = "product_seq_gen", sequenceName = "product_idproduct_seq", initialValue = 1, allocationSize = 1)
@Column(name = "idproduct", unique = true, nullable = false)
public Long getIdProduct() {
return idProduct.get();
}

public LongProperty idProductProperty() {
return idProduct;
}

public void setIdProduct(Long idProduct) {
this.idProduct.set(idProduct);
}

@Column(name = "nameAr")
public String getNameAr() {
return nameAr.get();
}

public StringProperty nameArProperty() {
return nameAr;
}

public void setNameAr(String nameAr) {
this.nameAr.set(nameAr);
}

@Column(name = "nameFr")
public String getNameFr() {
return nameFr.get();
}

public StringProperty nameFrProperty() {
return nameFr;
}

public void setNameFr(String nameFr) {
this.nameFr.set(nameFr);
}

@Column(name = "preference")
public String getPreference() {
return preference.get();
}

public StringProperty preferenceProperty() {
return preference;
}

public void setPreference(String preference) {
this.preference.set(preference);
}

@Column(name = "qtyStart")
public double getQtyStart() {
return qtyStart.get();
}

public DoubleProperty qtyStartProperty() {
return qtyStart;
}

public void setQtyStart(double qtyStart) {
this.qtyStart.set(qtyStart);
}

@Column(name = "qtyInHand")
public double getQtyInHand() {
return qtyInHand.get();
}

public DoubleProperty qtyInHandProperty() {
return qtyInHand;
}

public void setQtyInHand(double qtyInHand) {
this.qtyInHand.set(qtyInHand);
}

@Column(name = "sellPrice")
public double getSellPrice() {
return sellPrice.get();
}

public DoubleProperty sellPriceProperty() {
return sellPrice;
}

public void setSellPrice(double sellPrice) {
this.sellPrice.set(sellPrice);
}

@Column(name = "purchasePrice")
public double getPurchasePrice() {
return purchasePrice.get();
}

public DoubleProperty purchasePriceProperty() {
return purchasePrice;
}

public void setPurchasePrice(double purchasePrice) {
this.purchasePrice.set(purchasePrice);
}

@Column(name = "taxe")
public double getTaxe() {
return taxe.get();
}

public DoubleProperty taxeProperty() {
return taxe;
}

public void setTaxe(double taxe) {
this.taxe.set(taxe);
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.product", cascade=CascadeType.ALL)
public Set<LineCommand> getLineItems() {
return lineItems;
}

public void setLineItems(Set<LineCommand> lineItems) {
this.lineItems = lineItems;
}

}

购买:

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

public Purchase() {
this.idPurchase = new SimpleLongProperty();
this.codePurchase = new SimpleStringProperty();
this.datePurchase = new SimpleObjectProperty<>();
this.totalHt = new SimpleDoubleProperty();
this.tva = new SimpleDoubleProperty();
this.totalTTC = new SimpleDoubleProperty();
}

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "purchase_seq_gen")
@SequenceGenerator(name = "purchase_seq_gen", sequenceName = "purchase_idpurchase_seq", initialValue = 1, allocationSize = 1)
@Column(name = "idpurchase", unique = true, nullable = false)
public long getIdPurchase() {
return idPurchase.get();
}

public LongProperty idPurchaseProperty() {
return idPurchase;
}

public void setIdPurchase(long idPurchase) {
this.idPurchase.set(idPurchase);
}

@Column(name = "code")
public String getCodePurchase() {
return codePurchase.get();
}

public StringProperty codePurchaseProperty() {
return codePurchase;
}

public void setCodePurchase(String codePurchase) {
this.codePurchase.set(codePurchase);
}

@Column(name = "date")
public Timestamp getDatePurchase() {
return datePurchase.get();
}

public ObjectProperty<Timestamp> datePurchaseProperty() {
return datePurchase;
}

public void setDatePurchase(Timestamp datePurchase) {
this.datePurchase.set(datePurchase);
}

@Column(name = "totalHt")
public double getTotalHt() {
return totalHt.get();
}

public DoubleProperty totalHtProperty() {
return totalHt;
}

public void setTotalHt(double totalHt) {
this.totalHt.set(totalHt);
}

@Column(name = "tva")
public double getTva() {
return tva.get();
}

public DoubleProperty tvaProperty() {
return tva;
}

public void setTva(double tva) {
this.tva.set(tva);
}

@Column(name = "totalTTC")
public double getTotalTTC() {
return totalTTC.get();
}

public DoubleProperty totalTTCProperty() {
return totalTTC;
}

public void setTotalTTC(double totalTTC) {
this.totalTTC.set(totalTTC);
}


@OneToMany(mappedBy = "pk.purchase",
cascade = CascadeType.ALL)
public Set<LineCommand> getLineItems() {
return this.lineItems;
}

public void setLineItems(Set<LineCommand> lineItems) {
this.lineItems = lineItems;
}

}

购买产品:

@Entity
@Table(name = "purchaseProduct")
@Access(AccessType.PROPERTY)
@AssociationOverrides({
@AssociationOverride(name = "pk.product",
joinColumns = @JoinColumn(name = "idProduct")),
@AssociationOverride(name = "pk.purchase",
joinColumns = @JoinColumn(name = "idPurchase"))})
public class LineCommand {

// private LongProperty idProduct;
// private LongProperty idCommand;
private DoubleProperty qty;
private DoubleProperty sellPrice;
private DoubleProperty subTotal;

private LineCommandId compositePrimaryKey = new LineCommandId();

@EmbeddedId
public LineCommandId getCompositePrimaryKey() {
return compositePrimaryKey;
}

public void setCompositePrimaryKey(LineCommandId compositePrimaryKey) {
this.compositePrimaryKey = compositePrimaryKey;
}


private Product product;
private Purchase purchase;

public LineCommand() {
// this.idProduct = new SimpleLongProperty();
// this.idCommand = new SimpleLongProperty();
this.qty = new SimpleDoubleProperty();
this.sellPrice = new SimpleDoubleProperty();
this.subTotal = new SimpleDoubleProperty();
// Bind subtotal to qty * sellPrice
this.subTotalProperty().bind(Bindings.multiply(this.qtyProperty(), this.sellPriceProperty()));
}

public LineCommand(double qty, double sellPrice) {
// this.idProduct.set(idProduct);
// this.idCommand.set(idCommand);
this.qty.set(qty);
this.sellPrice.set(sellPrice);

// Bind subtotal to qty * sellPrice
this.subTotalProperty().bind(Bindings.multiply(this.qtyProperty(), this.sellPriceProperty()));
}

@Column(name = "qty")
public double getQty() {
return qty.get();
}

public DoubleProperty qtyProperty() {
return qty;
}

public void setQty(double qty) {
this.qty.set(qty);
}

@Column(name = "price")
public double getSellPrice() {
return sellPrice.get();
}

public DoubleProperty sellPriceProperty() {
return sellPrice;
}

public void setSellPrice(double sellPrice) {
this.sellPrice.set(sellPrice);
}


public double getSubTotal() {
return subTotal.get();
}

public DoubleProperty subTotalProperty() {
return subTotal;
}

@Transient
public Product getProduct() {
return product;
}

public void setProduct(Product product) {
this.product = product;
}

@Transient
public Purchase getPurchase() {
return purchase;
}

public void setPurchase(Purchase purchase) {
this.purchase = purchase;
}
}

购买产品复合键

@Embeddable
public class LineCommandId implements Serializable{
private Product product ;
private Purchase purchase ;

@ManyToOne(cascade = CascadeType.ALL)
public Product getProduct() {
return product;
}

public void setProduct(Product product) {
this.product = product;
}

@ManyToOne(cascade = CascadeType.ALL)
public Purchase getPurchase() {
return purchase;
}

public void setPurchase(Purchase purchase) {
this.purchase = purchase;
}
}

当我执行上述代码时,出现此错误:

org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: model.LineCommand.pk.product in model.Product.lineItems
at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:769)
at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:719)
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:54)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1655)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1623)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:418)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:87)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:692)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
at util.DatabaseUtil.buildSessionFactory(DatabaseUtil.java:17)
at util.DatabaseUtil.<clinit>(DatabaseUtil.java:11)
at dao.DAO.<init>(DAO.java:13)
at dao.ProductDAO.<init>(ProductDAO.java:14)
at controller.product.productController.parentTableProperties(productController.java:79)
at controller.product.productController.tableProperties(productController.java:74)
at controller.product.productController.initialize(productController.java:66)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2445)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2413)
at mains.start(mains.java:21)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$159(LauncherImpl.java:863)
at com.sun.javafx.application.LauncherImpl$$Lambda$52/479874812.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$172(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl$$Lambda$48/704060124.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
at com.sun.javafx.application.PlatformImpl$$Lambda$50/1324097194.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(PlatformImpl.java:294)
at com.sun.javafx.application.PlatformImpl$$Lambda$49/1608446104.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$145(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication$$Lambda$38/1378653614.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$152(LauncherImpl.java:182)
at com.sun.javafx.application.LauncherImpl$$Lambda$2/932172204.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ExceptionInInitializerError
at dao.DAO.<init>(DAO.java:13)
at dao.ProductDAO.<init>(ProductDAO.java:14)
at controller.product.productController.parentTableProperties(productController.java:79)
at controller.product.productController.tableProperties(productController.java:74)
at controller.product.productController.initialize(productController.java:66)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2445)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2413)
at mains.start(mains.java:21)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$159(LauncherImpl.java:863)
at com.sun.javafx.application.LauncherImpl$$Lambda$52/479874812.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$172(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl$$Lambda$48/704060124.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
at com.sun.javafx.application.PlatformImpl$$Lambda$50/1324097194.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(PlatformImpl.java:294)
at com.sun.javafx.application.PlatformImpl$$Lambda$49/1608446104.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$145(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication$$Lambda$38/1378653614.run(Unknown Source)
... 1 more
Caused by: java.lang.RuntimeException: There was an error building the factor
at util.DatabaseUtil.buildSessionFactory(DatabaseUtil.java:20)
at util.DatabaseUtil.<clinit>(DatabaseUtil.java:11)
... 23 more
DEBUG - Connection pool now considered primed; min-size will be maintained

最佳答案

参数mappedBy应该是所属类的字段或属性,而不是关系名称,因此您需要 mappedBy = "purchase"mappedBy = "product" 。事实上,使用复合键,它应该是 @IdClass 中的属性名称。这就是映射关系的那部分。

如果您要遵循此路径,那么您还应该删除 @EmbeddedId注释并将其替换为 @IdClass - 它更加干净、简单并且符合 JPA 标准。

您可以删除对 compositePrimaryKey 的任何引用并替换@Transient方法上的注释 getProduct()getPurchase() LineCommand的类:

@Id
@ManyToOne
@JoinColumn(name = "idproduct", updatable = false, insertable = false, referencedColumnName = "idproduct")

只需修改这些方法即可使用 Product 的实际实例和Purchase ,您需要将其添加到 LineCommand类而不是 compositePrimaryKey .

当然,你的@Embeddable LineCommandId那么类应该没有注释,因为它将被用作 @IdClass (请参阅下文了解为什么此处使用 Integer 而不是 Long):

@SuppressWarnings("serial")
public class LineCommandId implements Serializable {
private Integer product;
private Integer purchase;
public Integer getProduct() {
return product;
}
public void setProduct(Integer idproduct) {
this.product = idproduct;
}
public Integer getPurchase() {
return purchase;
}
public void setPurchase(Integer idpurchase) {
this.purchase = idpurchase;
}
public boolean equals(Object foo) {
if (foo == null || foo.getClass() != this.getClass())
return false;
LineCommandId src = (LineCommandId)foo;
if ((this.getProduct() == src.getProduct()) &&
(this.getPurchase() == src.getPurchase()))
return true;
return false;
}
public int hashCode() {
// implement
return someHashCode;
}
}

不过,您需要确保您的基本实体(例如 Product )使用 LineCommandId 中的字段名称。在其 mappedBy @OneToMany 的属性注释。

我注意到的另一件事是你计算 subTotal动态属性。由于它也不是数据库架构的一部分,因此 that 是您需要使用 @Transient 进行注释的属性。 ,否则您将收到有关 Hibernate 的异常 unable to find setter .

NullPointerException最有可能是由于您的包装对象返回 null来自get()方法,例如 idProduct属性,当包装对象未初始化时:

public Long getIdProduct() {
return idProduct.get();
}

更可能的 NPE 是您的某些 getter 方法使用自动装箱从非原始类型转换为原始类型:

public long getIdPurchase() {
return idPurchase.get();
}

如果idPurchase.get()返回null ,自动装箱的隐式 null.longValue()将导致异常。

一旦解决了启动持久性单元的最初问题,您还会注意到 LongSERIAL 根本不兼容,您在表中使用的:SERIAL映射到INTEGERLong映射到BIGINT 。您可能想更改它以匹配。这也是为什么上面的例子LineCommandId正在使用 Integer s。

关于java - Hibernate 与额外列的多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35105493/

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