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;
}