On 13/09/2011 18:32, Stevan Buzejic wrote:
Greetings Dan,

I have managed to create Customer and Invoice classes and all
relationships between them (Using mutual registration patern). But then
the problem arises. I am using dnd viewer. When I right click on a
Customer and select new Customer option I want to add to that cutomer an
Invoice. So I press right click on mouse and select new Invoice (similar
use case like CarService application example from the book Domain driven
design using Naked Objects, when I want to add a car to a customer).
After that I fill the form for creating new Invoice with some data and
press save button. Everithing it’s ok. But now I want to save my
Customer. When I press the save button on a Customer form, exception arises:

_org.apache.isis.runtimes.dflt.runtime.persistence.NotPersistableException_:
Object already persistent:
PojoAdapter@1be032b[PR~~:OID#5+,specification=Customer,version=1,pojo-toString=dom.masterapp.Customer$$EnhancerByCGLIB$$131323de@68cb669d,pojo-hash=#68cb669d
<mailto:PojoAdapter@1be032b[PR~~:OID#5+,specification=Customer,version=1,pojo-toString=dom.masterapp.Customer$$EnhancerByCGLIB$$131323de@68cb669d,pojo-hash=#68cb669d>]

etc. I know why it is happening, the Customer is saved when I save the
Invoice, so when I hit save on Cusotmer form, it tries to save it again
but this customer is already persisted. Is there any techique to avoid
this problem or any example on web where I can find solution for this?I
know how to achieve this using conventional programming and various
technologies, but I am not sure if and how it can be done with Your
framework.

Assuming that your domain objects are inheriting from oai.applib.AbstractDomainObject, you'll find that they inherit an isPersistent() method which you can check.

If you aren't inheriting from that adapter class, then you can use can DomainObjectContainer#isPersistent(object).

As a general remark, as you've found out, having graphs of transient objects (Customer and Invoice) can be quite tricky to code correctly. One choice is simply to not allow it: disable or hide the action to create a new invoice until the customer is persistent, eg:

public class Customer {
  ...
  public String disableNewInvoice() {
    return isPersistent()?"save customer first": null;
  }
}

If, however, creating a Customer and an Invoice at the same time is a common use case, then you have a few other choices.

One is to provide an action, probably on CustomerRepository, to create both:

public class CustomerRepository {
  ..
  public Customer invoiceNewCustomer(
     /// ... params for mandatory customer properties ...
     /// ... params for mandatory invoice properties ...
     ) {
    Customer cust = container.newTransientInstance(Customer.class);
    Invoice inv = container.newTransientInstance(Invoice.class);

    // ... set properties on both, and wire together ...

    container.persist(cust);
    container.persist(inv);
}

Alternatively, you could introduce a use case/process object model object that acts as a wizard to ask for this information. The process object would never be persisted, but would have a complete() or finish() action that would do the necessary.

public class CustomerRepository {
  ...
  public NewCustomerWizard newCustomer() {
    return container.newTransientInstance(NewCustomerWizard.class);
  }
}

@NotPersistable
public class NewCustomerWizard {

  // properties for customer
  // properties for invoice

  public Customer finish() {
    // similar to the invoiceNewCustomer action shown above
  }
}


Hopefully the above gives you some ideas...





About new viewer and about participating in Your projects, thanks for
offering me a cooperation, I will have Your proposal in my mind.
Currently I am very busy, doing some student project in Clojure language
and exploring capabilities of Your framework.

Very nice. It'd be interesting to get your thoughts on whether Clojure works as being a language suitable for expressing domain object models. (I've bought a book on it myself but haven't got past opening the front cover).


 Once again thanks for
response and hoping You could provide me ansvers for current problem.

let us know how you get on.

Dan


  Thanks in advanace,
--
*/Stevan Buzejić/*
*/063/628-238/*
*/063/175-45-86/*


Reply via email to