我有以下课程:
@Entity
@Table(name="ripa_request")
public class ReturningInvoiceRequest implements EntityKey<Long> {
public enum ReturningInvoiceRequestStatus {
/**
* This status means that the products for this request are chosen, but not confirmed at all.
*/
WAITING_TO_SEND("Aguardando envio para o fornecedor"),
/**
* This status means that the returning request is done but the supplier needs to approve the chosen products.
*/
WAITING_FOR_ACCEPTANCE("Aguardando aprovação do fornecedor"),
/**
* This status means that the invoice was generated with the returning request products and the products are dispatched.
*/
INVOICE_DISPATCHED("Nota Fiscal de devolução emitida"),
/**
* This status means that something wrong happened on the returning request process.
*/
INVALID("Requisição inválida");
private String message;
private ReturningInvoiceRequestStatus(String message) {
this.message = message;
}
/* (non-Javadoc)
* @see java.lang.Enum#toString()
*/
@Override
public String toString() {
return message;
}
}
@Id
@GeneratedValue
private Long id;
/**
* Mapping for the Products associated to this request with related information: Product Invoice's included with chosen count.
*/
@ElementCollection(targetClass=ProductRequestContext.class)
@MapKeyJoinColumn(name="product_id")
@CollectionTable(name="ripa_request_product", joinColumns=@JoinColumn(name="request_id"))
@Columns(columns={@Column(name="invoice_id"), @Column(name="count")})
private Map<Product, Collection<ProductRequestContext>> productCountMap;
@Temporal(TemporalType.TIMESTAMP)
private Date date;
@Enumerated(EnumType.STRING)
private ReturningInvoiceRequestStatus status;
public ReturningInvoiceRequest() {
this.status = ReturningInvoiceRequestStatus.WAITING_TO_SEND;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Collection<Product> getProductList() {
return this.productCountMap == null ? new ArrayList<Product>() : this.productCountMap.keySet();
}
public void setProductList(Collection<Product> productList) {
this.productCountMap = new HashMap<>();
for (Product product : productList) {
if (product.getInvoiceList() == null || product.getInvoiceList().isEmpty()) {
setStatus(ReturningInvoiceRequestStatus.INVALID);
break;
} else {
List<ProductRequestContext> productContextList = new ArrayList<>();
for (Invoice invoice : product.getInvoiceList()) {
productContextList.add(new ProductRequestContext(invoice.getId(), product.getCount(invoice)));
}
this.productCountMap.put(product, productContextList);
}
}
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public ReturningInvoiceRequestStatus getStatus() {
return status;
}
public void setStatus(ReturningInvoiceRequestStatus status) {
this.status = status;
}
/**
* Return the Invoice associated to the informed Product of this request
* @param product Product business entity
* @return <code>Invoice</code> Invoice business entity
*/
public Invoice getInvoice(Product product) {
for (Product requestProduct : getProductList()) {
if (product.equals(requestProduct)) {
Collection<ProductRequestContext> contextList = (Collection<ProductRequestContext>) this.productCountMap.get(requestProduct);
for (ProductRequestContext context : contextList) {
Long invoiceID = context.getRequestInvoiceID();
for (Invoice reqInvoice : requestProduct.getInvoiceList()) {
if (invoiceID.equals(reqInvoice.getId())) {
return reqInvoice;
}
}
}
}
}
return null;
}
/**
* Return the quantity of the informed Product selected for this request.
* @param product Product business entity
* @return
*/
public Integer getCount(Product product) {
for (Product requestProduct : getProductList()) {
if (product.equals(requestProduct)) {
Collection<ProductRequestContext> contextList = (Collection<ProductRequestContext>) this.productCountMap.get(requestProduct);
for (ProductRequestContext context : contextList) {
Long invoiceID = context.getRequestInvoiceID();
for (Invoice reqInvoice : requestProduct.getInvoiceList()) {
if (invoiceID.equals(reqInvoice.getId())) {
return context.getRequestCount();
}
}
}
}
}
return null;
}
/* (non-Javadoc)
* @see br.com.mls.eanf.entity.ifc.EntityKey#getKey()
*/
public Long getKey() {
return id;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ReturningInvoiceRequest other = (ReturningInvoiceRequest) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.id == null ? super.toString() : this.id.toString();
}
@Embeddable
public static class ProductRequestContext {
/**
* Sequence identifier for the Invoice registry on this context.
*/
@Column(name="invoice_id")
private long requestInvoiceID;
@Column(name="count")
private int requestCount;
public ProductRequestContext() {
}
ProductRequestContext(Long invoiceID, Integer count) {
this.requestInvoiceID = invoiceID;
this.requestCount = count;
}
public Long getRequestInvoiceID() {
return requestInvoiceID;
}
public void setRequestInvoiceID(Long invoiceID) {
this.requestInvoiceID = invoiceID;
}
public int getRequestCount() {
return requestCount;
}
public void setRequestCount(int count) {
this.requestCount = count;
}
}
}
问题出现在与元素集合的映射关系上,在插入 ReturningInvoiceRequest 实体期间(通过 EntityManager 的 persit 方法):
javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of br.com.mls.ripa.domain.model.product.ReturningInvoiceRequest$ProductRequestContext.requestCount
在我的研究中,我发现了一些关于地图值不支持休眠的信息,以及http://blog.xebia.com/2007/10/05/mapping-multimaps-with-hibernate/上的 MultiMap 方法,但我不知道它是否能解决我的问题
我还尝试使用 Google Collections 中的 Multimap 类来抑制 Collection 值,并且也不起作用,因为它没有扩展 java.util.Map,这是 hibernate 理解的,而 apache-collections MultiMap 没有支持泛型,这是 Hibernate 映射所必需的
我正在使用 Hibernate 3.6.9,但在 4.1.8 版本上仍然会发生错误。
谢谢