I’m trying to create a custom datatype for a phone number. I’ve been able to get a Long datatype to work but am stumped with String. What I’ve done so far:
Create a datatype class:
package com.examples.datatypes;
import ...
public class PhoneDatatype extends StringDatatype implements Datatype<String> {
// This field is required for Studio even if you don't use it in code
public static final String NAME = "string";
@Nonnull
@Override
public String format(Object value) {
// input is raw numbers, output +1 2345 6789
return value == null ? "" : ((String)value).replaceFirst("(\\d+)(\\d{4})(\\d{4})", "+$1 $2 $3");
}
@Override
public String parse(String value) {
// strip out non-numeric chars
StringBuilder parsed = new StringBuilder();
for (int i=0;i<value.length();i++) {
if (Character.isDigit(value.charAt(i))) {
parsed.append(value.charAt(i));
}
}
return parsed.toString();
}
}
Everything compiles and server starts fine, no errors that I can see in the logs. Values are saved and retrieved but just not being formatted and parsed. Any idea what I’m missing?
Maybe your datatype doesn’t work because you have given the existing name “string” to it.
I’ve just updated the sample application here and added your PhoneDatatype. There is a problem with using a String-based datatype in FieldGroup so I had to create a custom field, see CustomerEdit.java.
Consider also using MaskedField for phone numbers - it can be more convenient for users.
Thanks for the tip on MaskedField, that actually does the trick for me.
On the original question, I had tried naming it uniquely but my app wouldn’t load hence I tried setting it to “string”. I’ve tried it in two different projects (in case I some how messed up my other project) but still doesn’t load. As I mentioned, no problems with other non-string datatypes.
Fyi, the error in the logs are:
23:03:25.928 ERROR c.h.cuba.core.sys.AppContextLoader - Error initializing application
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: java.lang.IllegalArgumentException: Datatype phone is not found
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:431) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373) ~[spring-tx-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at com.haulmont.cuba.core.sys.TransactionImpl.<init>(TransactionImpl.java:58) ~[cuba-core-6.4.2.jar:6.4.2]
at com.haulmont.cuba.core.sys.PersistenceImpl.createTransaction(PersistenceImpl.java:121) ~[cuba-core-6.4.2.jar:6.4.2]
at com.haulmont.cuba.security.app.LoginWorkerBean.loginAnonymous(LoginWorkerBean.java:213) ~[cuba-core-6.4.2.jar:6.4.2]
at com.haulmont.cuba.security.app.LoginWorkerBean.initializeAnonymousSession(LoginWorkerBean.java:511) ~[cuba-core-6.4.2.jar:6.4.2]
at com.haulmont.cuba.security.app.LoginWorkerBean.applicationStarted(LoginWorkerBean.java:521) ~[cuba-core-6.4.2.jar:6.4.2]
at com.haulmont.cuba.core.sys.AppContext.startContext(AppContext.java:234) ~[cuba-global-6.4.2.jar:6.4.2]
at com.haulmont.cuba.core.sys.AppContext$Internals.startContext(AppContext.java:289) ~[cuba-global-6.4.2.jar:6.4.2]
at com.haulmont.cuba.core.sys.AbstractWebAppContextLoader.contextInitialized(AbstractWebAppContextLoader.java:74) ~[cuba-global-6.4.2.jar:6.4.2]
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4813) [catalina.jar:8.0.35]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5272) [catalina.jar:8.0.35]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147) [catalina.jar:8.0.35]
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725) [catalina.jar:8.0.35]
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701) [catalina.jar:8.0.35]
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717) [catalina.jar:8.0.35]
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1092) [catalina.jar:8.0.35]
at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1834) [catalina.jar:8.0.35]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_66]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_66]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_66]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_66]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_66]
Caused by: javax.persistence.PersistenceException: java.lang.IllegalArgumentException: Datatype phone is not found
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:815) ~[eclipselink-2.6.2.cuba12.jar:2.6.2.cuba12]
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:205) ~[eclipselink-2.6.2.cuba12.jar:2.6.2.cuba12]
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:305) ~[eclipselink-2.6.2.cuba12.jar:2.6.2.cuba12]
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:337) ~[eclipselink-2.6.2.cuba12.jar:2.6.2.cuba12]
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:303) ~[eclipselink-2.6.2.cuba12.jar:2.6.2.cuba12]
at org.springframework.orm.jpa.JpaTransactionManager.createEntityManagerForTransaction(JpaTransactionManager.java:449) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:369) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE]
... 22 common frames omitted
Caused by: java.lang.IllegalArgumentException: Datatype phone is not found
at com.haulmont.chile.core.datatypes.Datatypes.get(Datatypes.java:160) ~[cuba-global-6.4.2.jar:6.4.2]
at com.haulmont.cuba.core.sys.MetaModelLoader.getDatatype(MetaModelLoader.java:676) ~[cuba-global-6.4.2.jar:6.4.2]
at com.haulmont.cuba.core.sys.MetaModelLoader.loadProperty(MetaModelLoader.java:269) ~[cuba-global-6.4.2.jar:6.4.2]
at com.haulmont.cuba.core.sys.MetaModelLoader.initProperties(MetaModelLoader.java:193) ~[cuba-global-6.4.2.jar:6.4.2]
at com.haulmont.cuba.core.sys.MetaModelLoader.loadClass(MetaModelLoader.java:120) ~[cuba-global-6.4.2.jar:6.4.2]
at com.haulmont.cuba.core.sys.MetaModelLoader.loadModel(MetaModelLoader.java:91) ~[cuba-global-6.4.2.jar:6.4.2]
at com.haulmont.cuba.core.sys.MetadataLoader.loadMetadata(MetadataLoader.java:103) ~[cuba-global-6.4.2.jar:6.4.2]
at com.haulmont.cuba.core.sys.MetadataImpl.initMetadata(MetadataImpl.java:202) ~[cuba-global-6.4.2.jar:6.4.2]
at com.haulmont.cuba.core.sys.MetadataImpl.getSession(MetadataImpl.java:69) ~[cuba-global-6.4.2.jar:6.4.2]
at com.haulmont.cuba.core.sys.persistence.EclipseLinkSessionEventListener.preLogin(EclipseLinkSessionEventListener.java:66) ~[cuba-core-6.4.2.jar:6.4.2]
at org.eclipse.persistence.sessions.SessionEventManager.preLogin(SessionEventManager.java:620) ~[eclipselink-2.6.2.cuba12.jar:2.6.2.cuba12]
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.preConnectDatasource(DatabaseSessionImpl.java:797) ~[eclipselink-2.6.2.cuba12.jar:2.6.2.cuba12]
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.login(DatabaseSessionImpl.java:773) ~[eclipselink-2.6.2.cuba12.jar:2.6.2.cuba12]
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:267) ~[eclipselink-2.6.2.cuba12.jar:2.6.2.cuba12]
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:731) ~[eclipselink-2.6.2.cuba12.jar:2.6.2.cuba12]
... 28 common frames omitted