JPAContainer and one to many relationship

Hi there,

I’ve a problem regarding a one to many relationship.
There is an entity class adresses with a one to many relationship on contacts.

I’m using Vaadin 7.01 and created a field group for the main view.
What I’m trying to do is to bind a table to the set off contacts in the adresses entity class.
I tried addNestedCointainerProperty but it can only be used on many to one relationships.

Any ideas how to do that?

Thanks in advance.

Reiner

What is the error you get ?

Some notes though :
make sure you have set the “mappedBy” property in the @OneToMany annotation and you have a reverse mapping ( ie bidirectional OneToMany in one entity and ManyToOne in the other entity ), If I remember correctly the JPAContainer’s code that process the MetaData of the entities need the mappedBy property for OneToMany mappings…

for example


  Domain {
     ...
    @NotNull
    @Valid
    @Size(min = 2)
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "domain")
    private java.util.Set<NameServerAttribute> nameservers = new java.util.HashSet<NameServerAttribute>(2);
    ...
 }

 NameServerAttribute {
    ...
    @NotNull
    @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH, CascadeType.REFRESH})
    @JoinColumn(name = Domain.PRIMARY_KEY, insertable = true, updatable = false)
    private Domain domain;
    ...
 }

Other than that you have to be a bit more specific on what your problem is.

Hello Petrus,

thank you for your quick response. I really appreciate it.
I think my bidrectional Domain relation is ok.
My question is, how to mingle a table component with the java.util.Set of the “master” domain class.
(In your example the nameservers)
I found a hint in the JPAContainer documentation of the Book of Vaadin 7.
In this chapter a FieldFactory with a Form is explained.
The FieldFactory uses a MasterDetailEditor to build an editable table component.
The Problem is, that in Vaadin 7 the Form Class is deprecated.
I’m using a Custom component together with a FieldGroup.
How do have to set the table ContainerDataSource for the binding to the Set of detail items?

It would be really nice to get any kind of sugestion on my problem.

Ah I think I understand your problem , JPAContainer currently lacks a FieldGroupFieldFactory Implementation .

If your masterItem originates from a JPAContainer . You should be able to simply bind it like


  fieldGroup.bind( 
    new com.vaadin.addon.jpacontainer.fieldfactory.MasterDetailEditor(  
        refToJpaContainerFieldFactory ,   // Needs a com.vaadin.addon.jpacontainer.fieldfactory.FieldFactory for the Table 
        ((JPAContainerItem<?>) masterItem).getContainer(),
        ((JPAContainerItem<?>) masterItem).getItemId() ,
        "detailPropertyID" ,
        layout ) ,    /// Here can be a problem if your fieldGroup is set to WriteThrough( true )... 
        "detailPropertyID" 
    );

But I would advise you to make your own MasterDetailEditor based on the JpaContainers MasterDetailEditor, The JPAContainers’ current version takes a component for the uiContext and in your case you have a FieldGroup not a Component . In many of my use cases I dont edit the entities directly via the JPAContainers , So I make a BeanItem from the entity I want to edit , and get the business layer to make/apply my modifications. I use customized versions of MasterDetailEditor that does not take a Container as a parameter , and instead of building a JPAContainer for the table, I use a simple BeanContainer from the detail property’s collection…

This is how I bind the Collection to the Container for BeanItems …


public class MasterDetailEditorForBeanItem  ...... 
  ....

   private void buildContainer(boolean writeThrough) {
        Class<?> masterEntityClass = masterEntity.getBean().getClass();
        referencedType = fieldFactory.detectReferencedType(propertyId, masterEntityClass);
        container = new BeanContainer(referencedType) {
            @Override
            public Item addItem(final Object itemId) throws UnsupportedOperationException {
                if (getBeanType().isInstance(itemId)) {
                    return addBean(itemId);
                } else {
                    throw new java.lang.IllegalArgumentException("The bean should be the ID");
                }
            }
        };
        container.setBeanIdResolver(new AbstractBeanContainer.BeanIdResolver<Object, Object>() {
            @Override
            public Object getIdForBean(Object bean) { 
                return bean; // The bean is its own ID ( make sure you implement equals(Object) properly )
            }
        });
        Collection<?> currentValues = (Collection<?>) masterEntity.getItemProperty(propertyId).getValue();
        Logger.getLogger(getClass().getName()).log(Level.INFO, "MasterDetailEditorForBeanItem BeanType:{0}  : {1}", new Object[]{masterEntityClass, currentValues});
        if (currentValues != null) {
            container.addAll(currentValues);
        }
   }

}

NOTE Also take care on how you implement the commit of your MasterDetailEditor, don’t simply use the table.getValue() , ie the selected items … get all the items of the beanContainer…

Hope this helps…

Thank you very much for the detailed information!
I’ll check this out.
Maybe I was to much focused on using JPAContainer :wink:

Hi everyone,

Iam trying to execute jpacontainer addressbook demo (which is in jpacontainer library jar file itself)using maven mvn jetty:run…while executing iam getting the fallowing error

[b]
[INFO]
Scanning for projects…
[ERROR]
The build could not read 1 project → [Help 1]

[ERROR]

[ERROR]
The project com.vaadin.demo:jpacontainer-addressbook-demo:3.0.0 (C:\te
mp\temp1\jpacontainer-addressbook-demo\pom.xml) has 1 error
[ERROR]
Non-resolvable parent POM: Failure to find com.vaadin.addon:jpaconta
iner-modules:pom:3.0.0 in http://www.eclipse.org/downloads/download.php?r=1&nf=1
&file=/rt/eclipselink/maven.repo was cached in the local repository, resolution
will not be reattempted until the update interval of EclipseLink Repo has elapse
d or updates are forced and ‘parent.relativePath’ points at wrong local POM @ li
ne 4, column 13 → [Help 2]

[ERROR]

[ERROR]
To see the full stack trace of the errors, re-run Maven with the -e swit
ch.
[ERROR]
Re-run Maven using the -X switch to enable full debug logging.
[ERROR]

[ERROR]
For more information about the errors and possible solutions, please rea
d the following articles:
[ERROR]
[Help 1]
http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildin
gException
[ERROR]
[Help 2]
http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableMo
delException
[/b]

Is it problem with the dependency version???and how i can resolve?..if not what is the possible pom.xml? can anybody help me on this…thanq

Hi,
We done a GWT application with hibernate and written code to clone the pojos to dtos to send the objects to client(and to avoid serialization exception)…in vaadin also cloning of POJOs required???

Hi guys!

Can someone put the code using Vaadin 7 and JPA container with automatic jpa field generation and jpa validator for fields.
I can not understand how it works with version 7.

FieldGroup group = new FieldGroup(item);
group.setFieldFactory( new FieldFactory ()); //this is not working

Спасибо!

I did a quick scan of JPAContainer 3.1 and it does not use FieldGroup yet, you have to use Forms (old Vaadin 6 style).

Actually, a Container or an Item does not need to do anything special to be used with a FieldGroup. Instead, it is the FieldGroup that queries the container using the generic Item interfaces, the same interfaces used by Vaadin 6 style forms.

That said, one can implement subclasses of FieldGroup that provide better support for specific kinds of Items. BeanFieldGroup does this, adding Bean Validators (which the generic FieldGroup doesn’t do) and a few other BeanItem specific enhancements. One could copy the relevant parts to write a custom JPAFieldGroup with bean validation.

I assume you mean some custom field factory in the code example, as FieldFactory is an interface and obviously you cannot instantiate an interface directly with “new”. Just saying “this is not working” does not really tell anything, so information about how it is not working would be necessary to say anything more about this (exception stack trace or other relevant information).

I should have elaborated a bit more, if he wants to make use of the FieldFactory provided by JPAContainer , he should make use of Forms.

Some of the components that JPAContainer’s FieldFactory use checks the uicontext like this

    boolean writeThrough = true;
    if (uiContext instanceof Form) {
        Form f = (Form) uiContext;
        writeThrough = f.isBuffered();
    }
    // No further checking for FieldGroup

So it probably wont work correctly if you have buffered = true on the FieldGroup.