HibernateException: найдены общие ссылки на коллекцию

По какой-то странной причине, когда я обновляюсь до Hibernate 4, я получаю следующее исключение: HibernateException: найдены общие ссылки на коллекцию

У меня есть следующие бобы, сопоставленные следующим образом:

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

}

Всякий раз, когда я устанавливаю новую коллекцию в bean-компоненте HibernateCustomerProduct, я получаю исключение. Это очень странно, так как у меня есть только одна коллекция в моем тесте, но она все еще жалуется на то, что уже есть другая. Как это возможно? Мой тест выглядит следующим образом:

    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 это работает просто отлично.


person Tranquilized    schedule 16.08.2012    source источник
comment
Возможный дубликат stackoverflow.com/questions/1692871/   -  person Amit Deshpande    schedule 16.08.2012
comment
Я уже смотрел на это, но кажется, что это неприменимо для моей ситуации, так как у меня есть только 1 коллекция в тесте.   -  person Tranquilized    schedule 16.08.2012


Ответы (1)


Похоже, это было связано с чем-то еще, что было введено в SessionFactory. При использовании аннотаций @PrePersist. При регистрации слушателей обычные вещи больше не работали должным образом, поэтому мы перестали использовать эти аннотации и вместо этого использовали аспекты Spring.

person Tranquilized    schedule 20.08.2012