HibernateException:找到对集合的共享引用

时间:2012-08-16 15:22:53

标签: spring hibernate hibernate-4.x spring-orm

由于某些奇怪的原因,当我升级到Hibernate 4时,我遇到以下异常: HibernateException:找到对集合的共享引用

我有以下bean映射如下:

@Entity(name = "CIN_PRODUCTS")
@Inheritance(strategy = InheritanceType.JOINED)
public class HibernateCustomerProduct extends AbstractUpdatableDomainObject<Long>       implements CustomerProduct {

/**
 * 
 */
private static final long serialVersionUID = -1146349249414760087L;

/** The name of the product. */
@BusinessField
private String name;

/** The type of product. */
@BusinessField
private ProductTypeCode productType;

/** The product identifier. */
@BusinessField
private Long productId;

/** The address where this product needs to be installed. */
@BusinessField
private Set<Address> addresses;

/** The external ID for a customer. */
@BusinessField
private Long customerId;

/** The provisioning status. */
@BusinessField
private ProvisioningStatus provisioningStatus;

/** The billing status. */
@BusinessField
private BillingStatus billingStatus;

/** The service ID that identifies the product. */
@BusinessField
private String serviceId;

/** The id of the service. */
@BusinessField
private ServiceIdType serviceIdType;

/** The id from the order line where this product refers to. */
@BusinessField
private Long orderLineId;

/** The id from the order where this product refers to. */
@BusinessField
private Long orderId;

/** The numbers that belong to this product. */
private Set<Number> numbers;

/**
 * Default constructor.
 */
public HibernateCustomerProduct() {
    billingStatus = BillingStatus.UNB;
    provisioningStatus = ProvisioningStatus.UPR;
}

@Override
@Id
@SequenceGenerator(name = "CIN_PRODUCTS_SEQ", initialValue = 1, allocationSize = 1, sequenceName = "CIN_PRODUCTS_SEQ")
@GeneratedValue(strategy = GenerationType.AUTO, generator = "CIN_PRODUCTS_SEQ")
@Column(name = "ID")
public Long getId() {
    return id;
}

@Override
@Column(name = "NAME", unique = false, nullable = false)
public String getName() {
    return name;
}

/**
 * @param name
 *        the name to set
 */
public void setName(final String name) {
    this.name = name;
}

@Override
@Type(type = "product_type")
@Column(name = "PTY_CODE", unique = false, nullable = false)
public ProductTypeCode getProductType() {
    return productType;
}

public void setProductType(final ProductTypeCode productType) {
    this.productType = productType;
}

@Override
@Column(name = "PRODUCT_ID", unique = false, nullable = false)
public Long getProductId() {
    return productId;
}

/**
 * @param productId
 *        the productId to set
 */
public void setProductId(final Long productId) {
    this.productId = productId;
}

/**
 * @return the installationAddress
 */
@Override
@OneToMany(mappedBy = "product", targetEntity = HibernateAddress.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
public Set<Address> getAddresses() {
    return addresses;
}

/**
 * @param address
 *        the installationAddress to set
 */
public void setAddresses(final Set<Address> addresses) {
    this.addresses = addresses;
}

/**
 * @return the customerId
 */
@Override
@Column(name = "CUSTOMER_ID", nullable = false)
public Long getCustomerId() {
    return customerId;
}

/**
 * @param customerId
 *        the customerId to set
 */
public void setCustomerId(final Long customerId) {
    this.customerId = customerId;
}

/**
 * @return the provisioningStatus
 */
@Override
@Type(type = "provisioning_status")
@Column(name = "PROVISIONING_STATUS", nullable = false)
public ProvisioningStatus getProvisioningStatus() {
    return provisioningStatus;
}

/**
 * @param provisioningStatus
 *        the provisioningStatus to set
 */
@Override
public void setProvisioningStatus(final ProvisioningStatus provisioningStatus) {
    this.provisioningStatus = provisioningStatus;
}

/**
 * @return the billingStatus
 */
@Override
@Type(type = "billing_status")
@Column(name = "BILLING_STATUS", nullable = false)
public BillingStatus getBillingStatus() {
    return billingStatus;
}

/**
 * @param billingStatus
 *        the billingStatus to set
 */
public void setBillingStatus(final BillingStatus billingStatus) {
    this.billingStatus = billingStatus;
}

/**
 * @return the serviceId
 */
@Override
@Column(name = "SERVICE_ID")
public String getServiceId() {
    return serviceId;
}

/**
 * @param serviceId
 *        the serviceId to set
 */
public void setServiceId(final String serviceId) {
    this.serviceId = serviceId;
}

/**
 * @return the serviceIdType
 */
@Override
@Type(type = "service_id_type")
@Column(name = "SDT_CODE")
public ServiceIdType getServiceIdType() {
    return serviceIdType;
}

/**
 * @param serviceIdType
 *        the serviceIdType to set
 */
public void setServiceIdType(final ServiceIdType serviceIdType) {
    this.serviceIdType = serviceIdType;
}

/**
 * @return the numbers
 */
@Override
@OneToMany(targetEntity = HibernateNumber.class, mappedBy = "product", cascade = CascadeType.ALL)
public Set<Number> getNumbers() {
    return numbers;
}

/**
 * @param numbers
 *        the numbers to set
 */
public void setNumbers(final Set<Number> numbers) {
    this.numbers = numbers;
}

/**
 * Adds the specified {@link Number} to this product.
 * 
 * @param number
 *        The number that will be added.
 */
public void addNumber(final Number number) {
    numbers.add(number);
}

/**
 * @return the orderLineId
 */
@Override
@Column(name = "ORDER_LINE_ID", nullable = false)
public Long getOrderLineId() {
    return orderLineId;
}

/**
 * @param orderLineId
 *        the orderLineId to set
 */
public void setOrderLineId(final Long orderLineId) {
    this.orderLineId = orderLineId;
}

/**
 * @return the orderId
 */
@Override
@Column(name = "ORDER_ID", nullable = false)
public Long getOrderId() {
    return orderId;
}

/**
 * @param orderId
 *        the orderId to set
 */
public void setOrderId(final Long orderId) {
    this.orderId = orderId;
}
}

@Entity(name = "CIN_NUMBERS")
public class HibernateNumber extends AbstractUpdatableDomainObject<Long> implements Number {

    /**
     * 
     */
    private static final long serialVersionUID = -1982958589971470757L;

    /** The phone number. */
    @BusinessField
    private String number;

    /** The mobile product related to this CLI. */
    @BusinessField
    private CustomerProduct product;

    @Override
    @Id
    @SequenceGenerator(name = "CIN_NUMBERS_SEQ", initialValue = 1, allocationSize = 1, sequenceName = "CIN_NUMBERS_SEQ")
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "CIN_NUMBERS_SEQ")
    @Column(name = "ID")
    public Long getId() {
        return id;
    }

    @Override
    @Column(name = "PHONE_NUMBER", unique = true, nullable = false)
    public String getNumber() {
        return number;
    }

    /**
     * @param number
     *        the number to set
     */
    public void setNumber(final String number) {
        this.number = number;
    }

    @JoinColumn(name = "PRD_ID")
    @ManyToOne(targetEntity = HibernateCustomerProduct.class, optional = false)
    public CustomerProduct getProduct() {
        return product;
    }

    /**
     * @param product
     *        the product to set
     */
    public void setProduct(final CustomerProduct product) {
        this.product = product;
    }

}

每当我在HibernateCustomerProduct bean上设置一个新集合时,我都会得到异常。这很奇怪,因为我的测试中只有一个集合,但它仍然抱怨已经有另一个集合了。怎么可能?我的测试如下所示:

    product = new HibernateCustomerProduct();
    product.setCreated(new Date());
    product.setCreatedBy("Salomo");
    product.setCustomerId(123L);
    product.setName("IPhone");
    product.setProductId(1l);
    product.setProductType(ProductTypeCode.MOBILE_SUBSCRIPTION);
    product.setServiceId("036545458874");
    product.setServiceIdType(ServiceIdType.MAIN_PHONE_NUMBER);
    product.setOrderId(24123l);
    product.setOrderLineId(2412l);

    final HibernateNumber number = new HibernateNumber();
    number.setCreated(new Date());
    number.setCreatedBy("sape");
    number.setNumber("0642165348");
    number.setProduct(product);

    final Set<Number> numbers = new HashSet<Number>();
    numbers.add(number);
    product.setNumbers(numbers);

    customerProductDao.save(product);
    customerProductDao.flush();

有人知道我做错了什么吗?在Hibernate 3中,这很好用。

1 个答案:

答案 0 :(得分:0)

这似乎与SessionFactory中引入的其他东西有关。使用@PrePersist注释时。注册监听器时,正常的东西不再正常工作,所以我们停止使用这些注释,而是使用Spring方面。