Hi all,
I’m trying to implement a specific collection validation.
This is the use case;
- entity Artist pays every year a Membership fee to be associated to organization
- she/he pays a first time association fee and next 5 years yearly-fee
- every year she/he have to pay within a certain date starting from year beginning
these are my requirements.
Entities: ArtistInfo and MembershipFee 1 to many composition (with type an enumeration which classify Fee type, first year or following years).
When creating new Fee I have to examine collection to validate insertion of new fee.
From ArtistInfo Editor I pass ad parameter ArtistInfo Entity to MembershipFee Editor but Membership Fees collection is empty (due to Lazy.Loading?):
So I have to hit database to get MembershipFee.
Validation is implemented in Editor postValidate() method to report internationalized messages in the standard way (adding errors messages). It is implemented applying different  groovy closures  to MembershipFee  collection.
To collect MembershipFees first I tryed with collectionDatasource, than I found datasource are better suited for editing/visualizing, so I tried JPQL query in DataManager and at the end I implemented a specific service (excessive only to get related entities in my opinion)
I get this error (head part):
java.lang.IllegalArgumentException: MetaClass not found for contactsclass
	at com.haulmont.cuba.core.sys.CachingMetadataSession.getClassNN(CachingMetadataSession.java:70)
	at com.haulmont.cuba.core.sys.MetadataImpl.getClassNN(MetadataImpl.java:319)
	at com.haulmont.cuba.core.sys.PersistenceSecurityImpl.applyConstraints(PersistenceSecurityImpl.java:75)
	at sun.reflect.GeneratedMethodAccessor170.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:84)
	at com.haulmont.cuba.core.sys.PerformanceLogInterceptor.aroundInvoke(PerformanceLogInterceptor.java:29)
	at sun.reflect.GeneratedMethodAccessor169.invoke(Unknown Source)
Similar in service.
Can I simply force reload of collection of related objects?
---------------------------- Editor code --------------------------------------------------------------------------
package pro.sysonline.contacts.web.membershipfee
import com.haulmont.cuba.core.global.DataManager
import com.haulmont.cuba.core.global.LoadContext
import com.haulmont.cuba.core.global.Messages
import com.haulmont.cuba.gui.components.AbstractEditor
import com.haulmont.cuba.gui.components.ValidationErrors
import groovy.transform.CompileStatic
import pro.sysonline.contacts.entity.ArtistInfo
import pro.sysonline.contacts.entity.MembershipFee
import pro.sysonline.contacts.entity.MembershipFeeType
import pro.sysonline.contacts.service.MembershipFeeService
import javax.inject.Inject
@CompileStatic
class MembershipFeeEdit extends AbstractEditor<MembershipFee> {
    private ArtistInfo a
    @Inject
    private DataManager dataManager
    @Inject
    private Messages messages
   @Inject
    private MembershipFeeService memberShipService
    /*@Inject
    protected Metadata metadata
*/
    @Override
    void init(Map<String, Object> params) {
        super.init(params)
        a = (ArtistInfo) params.get("artist")
    }
    // Initialize Editor for new MembershipFee Item
    @Override
    protected void initNewItem(MembershipFee item) {
        item.artistInfo = a
    }
    @Override
    void postValidate(ValidationErrors errors) {
        Integer MAX_YEARLY_FEE = 5
        MembershipFee it
        List<MembershipFee> l = new ArrayList<MembershipFee>()
        l = loadMembershipFees(a)
        if ((l != null) && (!l.isEmpty())) {
            // First Year already present
            if (item.type.equals(MembershipFeeType.FIRST_YEAR))
                if (l.any() { it.type == MembershipFeeType.FIRST_YEAR })
                    errors.add(messages.getMessage(getClass(), "errorFY"))
            // All Fees presents
            if (l.count() { it.type == MembershipFeeType.NEXT_YEAR } == MAX_YEARLY_FEE)
                errors.add(messages.getMessage(getClass(), "errorMAX_YF"))
        }
    }
    private List<MembershipFee> loadMembershipFees(ArtistInfo a) {
    /*    Session session = metadata.getSession()
        MetaClass metaClass1 = session.getClassNN("contacts$MembershipFee")*/
        /*LoadContext<MembershipFee> loadContext = LoadContext.create(MembershipFee.class)
                .setQuery(LoadContext.createQuery("select f from contacts$MembershipFee f where f.artistInfo.id = :artistId")
                .setParameter("artistId", a.id))
                .setView("membershipFee-basic")*/
        //return dataManager.loadList(loadContext)
        return memberShipService.getMemberShipFeesForArtist(a)
        // Temporary Workaround
        //return null
    }
}
---------------------------- Service code --------------------------------------------------------------------------
package pro.sysonline.contacts.service
import com.haulmont.cuba.core.EntityManager
import com.haulmont.cuba.core.Persistence
import com.haulmont.cuba.core.Transaction
import org.slf4j.Logger
import org.springframework.stereotype.Service
import pro.sysonline.contacts.entity.ArtistInfo
import pro.sysonline.contacts.entity.MembershipFee
import javax.inject.Inject
@Service(MembershipFeeService.NAME)
public class MembershipFeeServiceBean implements MembershipFeeService {
    @Inject
    Logger log
    @Inject
    private Persistence persistence
    @Override
    List<MembershipFee> getMemberShipFeesForArtist(ArtistInfo a) {
        EntityManager em = null
        Transaction tx = null
        com.haulmont.cuba.core.Query query = null
        List<MembershipFee>  l
        String queryStr = "select f from contacts$MembershipFee f where f.artistInfo = :artistId"
        try {
            tx = persistence.createTransaction()
            em = persistence.getEntityManager()
            query = em.createQuery(queryStr)
            query.setParameter("artistId",a.id)
q
            l = (List<MembershipFee>) query.getResultList()
            tx.commit()
        } catch (Exception ex) {
            log.debug(Class.getName())
        } finally {
            tx.end()
        }
        return ((null != l)  ? l : new ArrayList<MembershipFee>())
    }
}
Thank you in advance for your advice.
Fabrizio