刷新JPA实体时出错

Dón*_*nal 5 java stack-overflow hibernate jpa composite-key

我有以下域模型

Currency ----< Price >---- Product
Run Code Online (Sandbox Code Playgroud)

或者用英语

产品有一个或多个价格.每种价格均以特定货币计价.

Price有复合主密钥(由表示PricePK以下),这是由外键的对CurrencyProduct.下面是JPA注释的Java类的相关部分(大多数省略了getter和setter):

@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Currency {

    @Id 
    private Integer ix;

    @Column 
    private String name;

    @OneToMany(mappedBy = "pricePK.currency", cascade = CascadeType.ALL, orphanRemoval = true)
    @LazyCollection(LazyCollectionOption.FALSE)
    private Collection<Price> prices = new ArrayList<Price>();
}

@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Product {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @OneToMany(mappedBy = "pricePK.product", cascade = CascadeType.ALL, orphanRemoval = true)
    @LazyCollection(LazyCollectionOption.FALSE)
    private Collection<Price> defaultPrices = new ArrayList<Price>();
}

@Embeddable
public class PricePK implements Serializable {

    private Product product;    
    private Currency currency;

    @ManyToOne(optional = false)
    public Product getProduct() {
        return product;
    }

    @ManyToOne(optional = false)
    public Currency getCurrency() {
        return currency;
    }    
}

@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Price {

    private PricePK pricePK = new PricePK();

    private BigDecimal amount;

    @Column(nullable = false)
    public BigDecimal getAmount() {    
        return amount;
    }

    public void setAmount(BigDecimal amount) {    
        this.amount = amount;
    }

    @EmbeddedId
    public PricePK getPricePK() {
        return pricePK;
    }    

    @Transient
    public Product getProduct() {
        return pricePK.getProduct();
    }

    public void setProduct(Product product) {
        pricePK.setProduct(product);
    }

    @Transient
    public Currency getCurrency() {
        return pricePK.getCurrency();
    }

    public void setCurrency(Currency currency) {
        pricePK.setCurrency(currency);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试刷新一个实例时Product,我得到一个StackOverflowError,所以我怀疑上面的映射中存在某种循环(或其他错误),有人能发现它吗?

Aug*_*sto 2

我已经多次看到此错误,但我不记得确切的解决方案。我的想法是,您需要从 PricePK(均为 @ManyToOne)中删除映射,并将其替换为 Price 上的 @AssociationOverrides。

@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@AssociationOverrides({
    @AssociationOverride(name = "pricePK.product", 
                         joinColumns = @JoinColumn(name = "product_id")),
    @AssociationOverride(name = "pricePK.currency", 
                         joinColumns = @JoinColumn(name = "currency_id"))
})
public class Price extends VersionedEntity {
    [...]
}
Run Code Online (Sandbox Code Playgroud)

请检查列名称是否正确,因为我看不到产品或货币上的 id 列。