休眠与extras列的多对多关系 [英] Hibernate many to many relationship with extras columns

查看:126
本文介绍了休眠与extras列的多对多关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个与JAVA和HIBERNATE
进行多对多关系映射的问题我有表购买> ------------------<产品,所以我们得到另一个表
purchaseProduct,这里是DDL

  CREATE TABLE产品(
idProduct (50),
nameFr varchar(50),
首选项varchar(50),
qtyStart double PRECISION,
qtyInHand double PRECISION,
sellPrice双重PRECISION,
purchasePrice双重PRECISION,
taxe双重PRECISION
);


CREATE TABLE购买(
idPurchase序列主键,
代码varchar(50),
日期时间戳,
totalHt double PRECISION,
tva双精度,
totalTTC双精度
);


CREATE TABLE purchaseProduct(
idPurchase integer,
idProduct integer,
qty double PRECISION,
price double PRECISION,
主键(idProduct);
外键(idPurchase)引用购买(idPurchase),
外键(idProduct)引用product(idProduct)
);

以下是我的hibernate.cfg.xml配置:

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

< hibernate-configuration>

< session-factory>

<! - 数据库连接设置 - >
< 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方言 - >
< property name =dialect> org.hibernate.dialect.PostgreSQL82Dialect< / property>

<! - 将所有执行的SQL回复到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;
私人StringProperty首选项;
私人DoubleProperty qtyStart;
私人DoubleProperty qtyInHand;
私人DoubleProperty sellPrice;
private DoubleProperty purchasePrice;
私人DoubleProperty税;

私人设定< 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 =
@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);

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

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

public DoubleProperty qtyStartProperty(){
return qtyStart;
}

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

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

public DoubleProperty qtyInHandProperty(){
return qtyInHand;
}

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

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

public DoubleProperty sellPriceProperty(){
return sellPrice;
}

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

$ b $ @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;
私人DoubleProperty totalHt;
私人DoubleProperty tva;
私人DoubleProperty totalTTC;

私人设定< LineCommand> lineItems = new HashSet< LineCommand>(0);

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

$ b @Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator =purchase_seq_gen)
@SequenceGenerator(name =purchase_seq_gen,sequenceName = )
@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);

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

public StringProperty codePurchaseProperty(){
return codePurchase;
}

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

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


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

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

}

purchaseProduct:

  @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;
私人DoubleProperty qty;
私人DoubleProperty sellPrice;
private DoubleProperty subTotal;

private LineCommandId compositePrimaryKey = new LineCommandId();

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

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


私人产品产品;
私人购买购买;

public LineCommand(){
// this.idProduct = new SimpleLongProperty();
// this.idCommand = new SimpleLongProperty();
this.qty = new SimpleDoubleProperty();
this.sellPrice = new SimpleDoubleProperty();
this.subTotal = new SimpleDoubleProperty();
//将小计绑定到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);

//将小计绑定到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
公共购买getPurchase(){
返回购买;
}

public void setPurchase(购买购买){
this.purchase =购买;


$ / code $ / pre
$ b $ purchaseProduct复合键

  @Embeddable 
public class LineCommandId implements Serializable {
private Product product;
私人购买购买;

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

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


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

public void setPurchase(购买购买){
this.purchase =购买;


当我托盘执行上述代码时,错误:

  org.hibernate.AnnotationException:mappedBy引用模型中的未知目标实体属性:model.LineCommand.pk.product。 Product.lineItems $在org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:769)b 
$ b。在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)
在org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:418)
。在org.hibernate.boot.internal。 MetadataBuilderImpl.build(MetadataBuilderImpl.java:87)
在org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:692)
在org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java: 724)在util.DatabaseUtil.buildSessionFactory(DatabaseUtil.java:17)
位于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.l oadImpl(FXMLLoader.java:2552)
在javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2445)
在javafx.fxml.FXMLLoader.load(FXMLLoader.java:2413)
在mains.start(mains.java:21)
在com.sun.javafx.application.LauncherImpl.lambda $ launchApplication1 $ 159(LauncherImpl.java:863)
在com.sun.javafx.application。 LauncherImpl $$ Lambda $ 52 / 479874812.run(未知源代码)
at com.sun.javafx.application.PlatformImpl.lambda $ runAndWait $ 172(PlatformImpl.java:326)
at com.sun.javafx。 application.PlatformImpl $$ Lambda $ 48 / 704060124.run(未知来源)
at com.sun.javafx.application.PlatformImpl.lambda $ null $ 170(PlatformImpl.java:295)
at com.sun。 javafx.application.PlatformImpl $$ Lambda $ 50 / 1324097194.run(未知源)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda $ runLater $ 171(PlatformImpl.java:294)
,位于com.sun.javafx.application.PlatformImpl $$ Lambda $ 49/1 608446104.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher $ Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop (本地方法)
at com.sun.glass.ui.win.WinApplication.lambda $ null $ 145(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication $$ Lambda $ 38 / 1378653614.run(未知源)
在java.lang.Thread.run(Thread.java:745)
Application start方法中的异常
线程mainjava中的异常。 lang.RuntimeException:异常中的应用启动方法
。在com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
。在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)
导致:java.lang.ExceptionInInitializerError $ b $ 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)
。在com.sun.javafx.application.LauncherImpl.lambda $ $ launchApplication1 159(LauncherImpl.java:863)
。在com.sun.javafx.application.LauncherImpl $$ LAMBDA $ 52 / 479874812.run (未知来源)
at com.sun.javafx.application.PlatformImpl.lambda $ runAndWait $ 172(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl $$ Lambda $ 48/704060124 .run(未知源)
在com.sun.javafx.applicatio n.PlatformImpl.lambda $ null $ 170(PlatformImpl.java:295)
在com.sun.javafx.application.PlatformImpl $$ Lambda $ 50 / 1324097194.run(未知源代码)
在java.security。 AccessController.doPrivileged(本地方法)
at com.sun.javafx.application.PlatformImpl.lambda $ runLater $ 171(PlatformImpl.java:294)
at com.sun.javafx.application.PlatformImpl $$ Lambda $ 49 / 1608446104.run(未知来源)
at com.sun.glass.ui.InvokeLaterDispatcher $ Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication ._runLoop(Native方法)
at com.sun.glass.ui.win.WinApplication.lambda $ null $ 145(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication $$ Lambda $ 38 / 1378653614.run(未知源)
... 1 more
导致:java.lang.RuntimeException:在util.DatabaseUtil中构建因子
时发生错误。 buildSessionFactory(DatabaseUtil.java:20)
位于util.DatabaseUtil。< clinit>(DatabaseUtil.java:11)​​
... 23更多
DEBUG - 连接池现在被认为是启动的; min-size将保留


解决方案

参数< mappedBy 应该是拥有类的字段或属性,而不是关系名称,所以您需要 mappedBy =purchase mappedBy =product。事实上,对于组合键,它应该是 @IdClass 中映射该关系部分的属性的名称。



如果您要遵循此路径,则还应该删除 @EmbeddedId 注释,并将其替换为 @IdClass - 它更简洁,更简单,并且符合JPA。

您可以删除对 compositePrimaryKey 并替换 getProduct() getPurchase()方法上的 @Transient code> LineCommand class with:

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

只要修改这些方法以处理 Product Purchase ,你需要添加到 LineCommand 类而不是 compositePrimaryKey



当然,您的 @Embeddable LineCommandId 类应该没有注释,因为它将被使用作为 @IdClass (见下面为什么使用整数而不是 Long
pre $ @SuppressWarnings(serial)
public class LineCommandId implements Serializable {
私人整数产品;
私人整数购买;
public Integer getProduct(){
return product;
}
public void setProduct(Integer idproduct){
this.product = idproduct;
}
public Integer getPurchase(){
return return;
}
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; ((this.getProduct()== src.getProduct())&&
(this.getPurchase()== src.getPurchase()))
return true;
返回false;

public int hashCode(){
// implements
return someHashCode;


$ / code>

然而,你需要确定的是,你的 base 实体(例如, Product )使用 LineCommandId 中字段的名称它的 mappedBy 属性 @OneToMany 注解。



我注意到的是,你在运行时计算 subTotal 属性。由于它也不是数据库模式的一部分,因此 是需要用 @Transient 注释的属性,否则您将得到一个异常Hibernate是无法找到setter



NullPointerException 很可能是由于你的包装器对象从 get()方法返回 null ,例如<$当包装器对象未初始化时,c $ c> idProduct 属性:

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





$ b

更可能的NPE是你的一些getter方法使用自动装箱转换的地方从非基元到原始:

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

$ / code>

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



一旦你过去了开始持久化单元的初始问题,你也会注意到 Long 从根本上不兼容 SERIAL ,您在表格中使用的是: SERIAL 映射到 INTEGER Long 映射到 BIGINT 。你可能想改变它来匹配。这也是为什么上面的例子 LineCommandId 正在使用整数 s。


I have an issue with many to many relationship mapping with JAVA and HIBERNATE I have table purchase >------------------< product, so we get another table purchaseProduct, here is the 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) 
);

Here is my hibernate.cfg.xml configuraiton :

<?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>

I take this approche to model many to many relationship:

Product mapping

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

}

Purchase :

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

}

purchaseProduct:

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

purchaseProduct composite key

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

When i tray to execute the above code i get this error :

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

解决方案

The parameter to mappedBy should be the field or property of the owning class, not the relation name, so you need mappedBy = "purchase" and mappedBy = "product". Infact, with composite keys, it should be the name of the property in @IdClass that is mapping that part of the relationship.

If you are going to follow this path, then you should also drop the @EmbeddedId annotation and replace it with @IdClass - it is much cleaner, easier and JPA-compliant.

You can remove any reference to compositePrimaryKey and replace @Transient annotations on the methods getProduct() and getPurchase() of the LineCommand class with:

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

Just modify those methods to work with actual instances of Product and Purchase, which you need to add to the LineCommand class instead of compositePrimaryKey.

Of course, your @Embeddable LineCommandId class should then have no annotations as it is going to be used as @IdClass (see below as to why Integer is used instead of Long here):

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

What you need to make sure though, is that your base entity (for example, Product) uses the name of the field from LineCommandId in its mappedBy attribute of @OneToMany annotation.

Another thing I noticed was that you calculate subTotal attribute on the fly. Since it is also not part of the database schema, that is the attribute you need to annotate with @Transient, or you will get an exception about Hibernate being unable to find setter.

The NullPointerException is most probably due to the fact your wrapper objects return null from the get() method on, say, idProduct attribute, when the wrapper object is not initialized:

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

An even more probable NPE is where some of your getter methods use autoboxing to convert from a non-primitive to primitive:

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

If idPurchase.get() returns null, the autoboxing's implicit null.longValue() will result in an exception.

Once you get past the initial problem of starting the persistence unit, you will also have noticed that Long is fundamentally incompatible with SERIAL, which you are using in your table: SERIAL maps to INTEGER whereas Long maps to BIGINT. You probably want to change that to match. That is also why the above example LineCommandId is using Integers.

这篇关于休眠与extras列的多对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆