Problem with embedded data types since upgrade to 6.3

I have an embedded datatype called ‘Money’ that’s used to store all monetary data in my application.

Since the upgrade to 6.3 it’s behaving quite strangely. For example, when I attempt to save a record with an embedded Money type I’m seeing the following error which causes the transaction to be rolled back:

(Im currently on the latest, 6.3.2 version)


WARN  [http-nio-8080-exec-7/app-core/admin] com.haulmont.cuba.security.app.EntityLog - Unable to log entity com.example.investment.NonCustodyHolding-51862fc2-c9d0-da20-3d9b-81d76aca0e49 [managed], id=51862fc2-c9d0-da20-3d9b-81d76aca0e49
java.lang.ClassCastException: com.example.investment.Money cannot be cast to java.util.UUID
at com.haulmont.cuba.security.app.EntityLog.getValueId(EntityLog.java:383) ~[cuba-core-6.3.2.jar:6.3.2]
at com.haulmont.cuba.security.app.EntityLog.writeAttribute(EntityLog.java:319) ~[cuba-core-6.3.2.jar:6.3.2]
at com.haulmont.cuba.security.app.EntityLog.registerModify(EntityLog.java:282) ~[cuba-core-6.3.2.jar:6.3.2]
at com.haulmont.cuba.core.sys.persistence.PersistenceImplSupport$OnCommitEntityVisitor.visit(PersistenceImplSupport.java:336) [cuba-core-6.3.2.jar:6.3.2]
at com.haulmont.cuba.core.sys.persistence.PersistenceImplSupport.beforeStore(PersistenceImplSupport.java:167) [cuba-core-6.3.2.jar:6.3.2]
at com.haulmont.cuba.core.sys.persistence.PersistenceImplSupport.traverseEntities(PersistenceImplSupport.java:154) [cuba-core-6.3.2.jar:6.3.2]
at com.haulmont.cuba.core.sys.persistence.PersistenceImplSupport$ContainerResourceSynchronization.beforeCommit(PersistenceImplSupport.java:247) [cuba-core-6.3.2.jar:6.3.2]
at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95) [spring-tx-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:932) [spring-tx-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:744) [spring-tx-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730) [spring-tx-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at com.haulmont.cuba.core.sys.TransactionImpl.commit(TransactionImpl.java:98) [cuba-core-6.3.2.jar:6.3.2]
at com.haulmont.cuba.core.app.RdbmsStore.commit(RdbmsStore.java:376) [cuba-core-6.3.2.jar:6.3.2]
at com.haulmont.cuba.core.app.DataManagerBean.commit(DataManagerBean.java:162) [cuba-core-6.3.2.jar:6.3.2]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
at com.haulmont.cuba.core.app.DataManagerBean$SecureDataManagerInvocationHandler.invoke(DataManagerBean.java:251) [cuba-core-6.3.2.jar:6.3.2]
at com.sun.proxy.$Proxy414.commit(Unknown Source) [na:na]
at com.haulmont.cuba.core.app.DataServiceBean.commit(DataServiceBean.java:38) [cuba-core-6.3.2.jar:6.3.2]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) [spring-aop-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) [spring-aop-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) [spring-aop-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85) [spring-aop-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at com.haulmont.cuba.core.sys.ServiceInterceptor.aroundInvoke(ServiceInterceptor.java:84) [cuba-core-6.3.2.jar:6.3.2]
at sun.reflect.GeneratedMethodAccessor164.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629) [spring-aop-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618) [spring-aop-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) [spring-aop-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168) [spring-aop-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) [spring-aop-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) [spring-aop-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at com.sun.proxy.$Proxy203.commit(Unknown Source) [na:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
at com.haulmont.cuba.core.sys.remoting.LocalServiceInvokerImpl.invoke(LocalServiceInvokerImpl.java:95) [cuba-core-6.3.2.jar:6.3.2]
at com.haulmont.cuba.web.sys.remoting.LocalServiceProxy$LocalServiceInvocationHandler.invoke(LocalServiceProxy.java:146) [cuba-web-6.3.2.jar:6.3.2]
at com.sun.proxy.$Proxy25.commit(Unknown Source) [na:na]
at com.haulmont.cuba.client.sys.DataManagerClientImpl.commit(DataManagerClientImpl.java:95) [cuba-client-6.3.2.jar:6.3.2]
at com.haulmont.cuba.gui.data.impl.GenericDataSupplier.commit(GenericDataSupplier.java:88) [cuba-gui-6.3.2.jar:6.3.2]
at com.haulmont.cuba.gui.data.impl.DsContextImpl.commit(DsContextImpl.java:164) [cuba-gui-6.3.2.jar:6.3.2]
at com.haulmont.cuba.gui.components.EditorWindowDelegate.commit(EditorWindowDelegate.java:256) [cuba-gui-6.3.2.jar:6.3.2]
at com.haulmont.cuba.web.gui.WebWindow$Editor.commitAndClose(WebWindow.java:1571) [cuba-web-6.3.2.jar:6.3.2]
at com.haulmont.cuba.gui.components.AbstractEditor.commitAndClose(AbstractEditor.java:110) [cuba-gui-6.3.2.jar:6.3.2]
at com.haulmont.cuba.gui.components.EditorWindowDelegate$2.actionPerform(EditorWindowDelegate.java:93) [cuba-gui-6.3.2.jar:6.3.2]
at com.haulmont.cuba.web.gui.components.WebButton.performAction(WebButton.java:44) [cuba-web-6.3.2.jar:6.3.2]
at com.haulmont.cuba.web.gui.components.WebButton.lambda$new$61446b05$1(WebButton.java:36) [cuba-web-6.3.2.jar:6.3.2]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:508) ~[vaadin-server-7.6.8.cuba.11.jar:7.6.8.cuba.11]
at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:198) ~[vaadin-server-7.6.8.cuba.11.jar:7.6.8.cuba.11]
at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:161) ~[vaadin-server-7.6.8.cuba.11.jar:7.6.8.cuba.11]
at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1030) ~[vaadin-server-7.6.8.cuba.11.jar:7.6.8.cuba.11]
at com.vaadin.ui.Button.fireClick(Button.java:377) ~[vaadin-server-7.6.8.cuba.11.jar:7.6.8.cuba.11]
at com.haulmont.cuba.web.toolkit.ui.CubaButton.fireClick(CubaButton.java:54) ~[cuba-web-6.3.2.jar:6.3.2]
at com.vaadin.ui.Button$1.click(Button.java:54) ~[vaadin-server-7.6.8.cuba.11.jar:7.6.8.cuba.11]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158) ~[vaadin-server-7.6.8.cuba.11.jar:7.6.8.cuba.11]
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118) ~[vaadin-server-7.6.8.cuba.11.jar:7.6.8.cuba.11]
at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:414) ~[vaadin-server-7.6.8.cuba.11.jar:7.6.8.cuba.11]
at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:274) ~[vaadin-server-7.6.8.cuba.11.jar:7.6.8.cuba.11]
at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:79) ~[vaadin-server-7.6.8.cuba.11.jar:7.6.8.cuba.11]
at com.haulmont.cuba.web.sys.CubaVaadinServletService$CubaUidlRequestHandler.lambda$synchronizedHandleRequest$109(CubaVaadinServletService.java:314) ~[cuba-web-6.3.2.jar:6.3.2]
at com.haulmont.cuba.web.sys.CubaVaadinServletService.withUserSession(CubaVaadinServletService.java:196) ~[cuba-web-6.3.2.jar:6.3.2]
at com.haulmont.cuba.web.sys.CubaVaadinServletService$CubaUidlRequestHandler.synchronizedHandleRequest(CubaVaadinServletService.java:314) ~[cuba-web-6.3.2.jar:6.3.2]
at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41) ~[vaadin-server-7.6.8.cuba.11.jar:7.6.8.cuba.11]
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1409) ~[vaadin-server-7.6.8.cuba.11.jar:7.6.8.cuba.11]
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:369) ~[vaadin-server-7.6.8.cuba.11.jar:7.6.8.cuba.11]
at com.haulmont.cuba.web.sys.CubaApplicationServlet.serviceAppRequest(CubaApplicationServlet.java:278) ~[cuba-web-6.3.2.jar:6.3.2]
at com.haulmont.cuba.web.sys.CubaApplicationServlet.service(CubaApplicationServlet.java:187) ~[cuba-web-6.3.2.jar:6.3.2]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[servlet-api.jar:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) ~[catalina.jar:8.0.35]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[catalina.jar:8.0.35]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-websocket.jar:8.0.35]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[catalina.jar:8.0.35]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[catalina.jar:8.0.35]
at com.haulmont.cuba.web.sys.CubaHttpFilter.handleNotFiltered(CubaHttpFilter.java:108) ~[cuba-web-6.3.2.jar:6.3.2]
at com.haulmont.cuba.web.sys.CubaHttpFilter.doFilter(CubaHttpFilter.java:95) ~[cuba-web-6.3.2.jar:6.3.2]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[catalina.jar:8.0.35]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[catalina.jar:8.0.35]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) ~[catalina.jar:8.0.35]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) ~[catalina.jar:8.0.35]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) ~[catalina.jar:8.0.35]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) ~[catalina.jar:8.0.35]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) ~[catalina.jar:8.0.35]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) ~[catalina.jar:8.0.35]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) ~[catalina.jar:8.0.35]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528) ~[catalina.jar:8.0.35]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099) ~[tomcat-coyote.jar:8.0.35]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) ~[tomcat-coyote.jar:8.0.35]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520) ~[tomcat-coyote.jar:8.0.35]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476) ~[tomcat-coyote.jar:8.0.35]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_101]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_101]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-util.jar:8.0.35]
at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_101]

This is my money data type:


@NamePattern("%s%s%s|ccyPrefix,value,ccyPostfix")
@MetaClass(name = "example$Money")
@Embeddable
public class Money extends EmbeddableEntity {
    private static final long serialVersionUID = 8670177103672671305L;

    @Column(name = "VALUE_", precision = 19, scale = 4)
    protected BigDecimal value;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "CURRENCY_ID")
    protected Currency currency;

    @Transient
    @MetaProperty
    protected String ccyPrefix;

    @Transient
    @MetaProperty
    protected String ccyPostfix;
}

and here’s the class that makes use of it (minus the getters/setters for brevity:


@NamePattern(" %s|investment")
@Table(name = "NON_CUSTODY_HOLDING")
@Entity(name = "example$NonCustodyHolding")
@EnableRestore
public class NonCustodyHolding extends StandardEntity {
    private static final long serialVersionUID = 248213542069481046L;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "INVESTMENT_ID")
    protected Investment investment;

    @Temporal(TemporalType.DATE)
    @Column(name = "INVESTMENT_DATE")
    protected Date investmentDate;

    @Embedded
    @AssociationOverrides({
        @AssociationOverride(name = "currency", joinColumns = @JoinColumn(name = "COST_CURRENCY_ID"))
    })
    @AttributeOverrides({
        @AttributeOverride(name = "value", column = @Column(name = "COST_VALUE_"))
    })
    protected Money cost = new Money();

    @Column(name = "UNITS", precision = 19, scale = 4)
    protected BigDecimal units;

    @Column(name = "PROD_INITIAL_CHARGE")
    protected String prodInitialCharge;

    @Column(name = "PROD_ANNUAL_CHARGE")
    protected String prodAnnualCharge;

    @Column(name = "ANNUAL_COMMISSION")
    protected String annualCommission;

    @Column(name = "INITIAL_COMMISSION")
    protected String initialCommission;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "NON_CUSTODY_PORTFOLIO_ID")
    protected NonCustodyPortfolio nonCustodyPortfolio;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "PARENT_HOLDING_ID")
    protected NonCustodyHolding parentHolding;



    @Composition
    @OnDelete(DeletePolicy.CASCADE)
    @OneToMany(mappedBy = "nonCustodyHolding", cascade = CascadeType.PERSIST)
    protected Set<HoldingStatus> statusHistory;



    @Composition
    @OnDelete(DeletePolicy.CASCADE)
    @OneToMany(mappedBy = "forHolding", cascade = CascadeType.PERSIST)
    protected Set<HoldingDocument> hasDocuments;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "PHASE_ID")
    protected Phase phase;

    @Transient
    @MetaProperty
    protected BigDecimal value;

    @Transient
    @MetaProperty
    protected Money price;

    @Transient
    @MetaProperty
    protected BigDecimal gainLoss;

    @Transient
    @MetaProperty
    protected Date priceDate;

    @Column(name = "PROVIDER_REF", unique = true, length = 25)
    protected String providerRef;
}

Hi.

As I understood from the description:

  1. In your application, Entity Log is switched on for the “NonCustodyHolding” entity.
  2. And the embedded “cost” attribute is selected for logging.

At the moment, the entity log could be written only for UUID entities. To prevent the exception exclude the “cost” attribute from logging.

The similar exception also occurs when the UUID entity has associations with non-UUID entity, and logging is enabled for the link-attribute.

Thank you for reporting the issue. We will fix it.

Hi Rostislav,

Thank you for the response - yes you’re absolutely correct in your assessment re entity logging.

Thank you for the workaround. Will the fix be in the next maintenance release?

Thanks again,

Chris

The issue is taken to work. We are planning to fix it in the next bugfix release.

Hi.

The issue is fixed in the platform version 6.3.3