Hibernate version: 3.4
Name and version of the database you are using: MySQL 5 (InnoDB)
Hi Leutz,
bin neu hier und hab eine Frage, die eventl Newbie-like sein könnte. Da es für mich jedoch nicht trivial genug ist, hier die Frage:
Wie kann ich eine 1:n Beziehung auf ein und dieselbe Tabelle mit Annotations machen? Der bisher existierende Code ermöglicht Problemloses hinzufügen, jedoch beim Löschen tritt eine Exception auf (s. unten). Mein Code sieht wie folgt aus:
Mein Code:
ProductDAO.java
Code:
//Package und Imports...
@Entity
@Table(name = "product")
public class ProductDAO {
private int id;
private boolean active;
private CustomerDAO customer;
private ProductTypeDAO productType;
private List<DailyBillDAO> dailyBills;
private List<RoleDAO> roles;
private ProductDAO masterProduct;
private List<ProductDAO> slaveProducts;
private Timestamp creationDate;
public ProductDAO() {}
/**
* Konstruktor für das Initialprodukt!
* @param productType
* @param customer
*/
public ProductDAO(ProductTypeDAO productType, CustomerDAO customer) {
this.active = true;
this.customer = customer;
this.customer.getProducts().add(this);
this.productType = productType;
this.productType.getProducts().add(this);
this.dailyBills = new ArrayList<DailyBillDAO>();
this.roles = new ArrayList<RoleDAO>();
this.slaveProducts = new ArrayList<ProductDAO>();
Date today = new Date();
this.creationDate = new Timestamp(today.getTime());
}
public ProductDAO(ProductTypeDAO productType, ProductDAO masterProduct, CustomerDAO customer) {
this.active = true;
this.customer = customer;
this.customer.getProducts().add(this);
this.productType = productType;
this.productType.getProducts().add(this);
this.dailyBills = new ArrayList<DailyBillDAO>();
this.roles = new ArrayList<RoleDAO>();
this.masterProduct = masterProduct;
Date today = new Date();
this.creationDate = new Timestamp(today.getTime());
}
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@NotNull
@Basic(optional=false)
@Column(name="id", nullable = false, unique = true)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
@NotNull
@Basic(optional=false)
@Column(name="active", nullable = false)
public boolean getActive() {
return this.active;
}
public void setActive(boolean active) {
this.active = active;
}
@ManyToOne
@JoinColumn(name = "customer")
@NotNull
@Basic(optional=false)
public CustomerDAO getCustomer() {
return this.customer;
}
public void setCustomer(CustomerDAO customer) {
this.customer = customer;
}
@ManyToOne
@JoinColumn(name = "productType")
@NotNull
@Basic(optional=false)
public ProductTypeDAO getProductType() {
return this.productType;
}
public void setProductType(ProductTypeDAO productType) {
this.productType = productType;
}
@OneToMany(mappedBy = "product")
@Cascade(CascadeType.ALL)
public List<RoleDAO> getRoles() {
return this.roles;
}
public void setRoles(List<RoleDAO> roles) {
this.roles = roles;
}
@ManyToMany(mappedBy = "products")
@Cascade(CascadeType.ALL)
public List<DailyBillDAO> getDailyBills() {
return dailyBills;
}
public void setDailyBills(List<DailyBillDAO> dailyBills) {
this.dailyBills = dailyBills;
}
@NotNull
@Basic(optional=false)
public Timestamp getCreationDate() {
return this.creationDate;
}
public void setCreationDate(Timestamp creationDate) {
this.creationDate = creationDate;
}
@ManyToOne
@JoinColumn(name = "product")
public ProductDAO getMasterProduct() {
return this.masterProduct;
}
public void setMasterProduct(ProductDAO masterProduct) {
this.masterProduct= masterProduct;
}
@OneToMany(mappedBy = "masterProduct")
@Cascade(CascadeType.DELETE_ORPHAN)
public List<ProductDAO> getSlaveProducts() {
return this.slaveProducts;
}
public void setSlaveProducts(List<ProductDAO> slaveProducts) {
this.slaveProducts= slaveProducts;
}
public String toString() {
return new String(
"\n\nProductType:\n" +
"=============\n" +
"id - " + this.id + "\n" +
"customer - " + this.customer.getName() + "\n" +
"productType - " + this.productType.getName() + "\n" +
"creationDate - " + this.creationDate.toString()
);
}
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o))
return false;
ProductDAO product = (ProductDAO) o;
if (customer != null ? !customer.equals(product.customer) : product.customer != null)
return false;
if (productType != null ? !productType.equals(product.productType) : product.productType != null)
return false;
if (creationDate != null ? !creationDate.equals(product.creationDate) : product.creationDate != null)
return false;
return true;
}
}
Test.java->void main()Code:
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
byte[] by = new byte[32];
Transaction tx = session.getTransaction();
ProductTypeDAO pt = new ProductTypeDAO("name", "description", 3.24, by, true);
CustomerDAO customer = new CustomerDAO("name");
ContactDAO contact1 = new ContactDAO(customer, "forename", "surname", "address", "city", "telephone", "email");
ContactDAO contact2 = new ContactDAO(customer, "forename2", "surname2", "address2", "city2", "telephone2", "email2");
UserDAO user1 = new UserDAO(contact1, "lameplaya1", "weiter1");
UserDAO user2 = new UserDAO(contact1, "lameplaya2", "weiter2");
BillingRecipientDAO br = new BillingRecipientDAO(customer,"forename", "surname", "address", "city", "telephone", "email","786893789", "758578345", 365);
BillingSenderDAO bs = new BillingSenderDAO(customer,"forename", "surname", "address", "city", "telephone", "email", by, by);
ProductDAO p1 = new ProductDAO(pt, customer);
p1.setMasterProduct(p1);
ProductDAO p2 = new ProductDAO(pt, p1, customer);
ProductDAO p3 = new ProductDAO(pt, p2,customer);
ProductDAO p4 = new ProductDAO(pt, p3,customer);
ProductDAO p5 = new ProductDAO(pt, p4,customer);
ProductDAO p6 = new ProductDAO(pt, p5,customer);
RoleDAO role1 = new RoleDAO(user1,p1);
RoleDAO role2 = new RoleDAO(user2,p2);
RoleDAO role3 = new RoleDAO(user1,p3);
RoleDAO role4 = new RoleDAO(user1,p4);
RoleDAO role5 = new RoleDAO(user2,p5);
RoleDAO role6 = new RoleDAO(user1,p6);
DailyBillDAO db1 = new DailyBillDAO(customer,p1);
DailyBillDAO db2 = new DailyBillDAO(customer,p2);
DailyBillDAO db3 = new DailyBillDAO(customer,p3);
DailyBillDAO db4 = new DailyBillDAO(customer,p4);
DailyBillDAO db5 = new DailyBillDAO(customer,p5);
DailyBillDAO db6 = new DailyBillDAO(customer,p6);
tx.begin();
session.persist(pt);
session.persist(customer);
session.persist(contact1);
session.persist(contact2);
session.persist(user1);
session.persist(user2);
session.persist(br);
session.persist(bs);
session.persist(p1);
session.persist(p2);
session.persist(p3);
session.persist(p4);
session.persist(p5);
session.persist(p6);
session.persist(role1);
session.persist(role2);
session.persist(role3);
session.persist(role4);
session.persist(role5);
session.persist(role6);
session.persist(db1);
session.persist(db2);
session.persist(db3);
session.persist(db4);
session.persist(db5);
session.persist(db6);
customer.getProducts().remove(p6);
customer.getDailyBills().remove(db6);
user1.getRoles().remove(role6);
pt.getProducts().remove(p6);
customer.getProducts().remove(p5);
customer.getDailyBills().remove(db5);
user1.getRoles().remove(role5);
customer.getProducts().remove(p4);
customer.getDailyBills().remove(db4);
user1.getRoles().remove(role4);
customer.getProducts().remove(p3);
customer.getDailyBills().remove(db3);
user1.getRoles().remove(role3);
customer.getProducts().remove(p2);
customer.getDailyBills().remove(db2);
user1.getRoles().remove(role2);
session.delete(p2);
tx.commit();
}
Die DAO-Klassen sind hier jeweils bidirektional miteinander verknüpft, daher löse ich vor dem Löschen natürlich die Abhängigkeiten!
Von Hibernate erzeuger SQL-Code:
Code:
CREATE TABLE IF NOT EXISTS `product` (
`id` int(11) NOT NULL auto_increment,
`product` int(11) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `FKED8DCCEFE44CAA61` (`product`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Fehlermeldung:Code:
Exception in thread "main" org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [dao.userManagement.RoleDAO#2]
at org.hibernate.impl.SessionImpl.forceFlush(SessionImpl.java:1014)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:165)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:94)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:218)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:131)
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:122)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:65)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at Test.main(Test.java:101)