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