I work with Spring MVC RESTful app and get the ConstraintViolationException while persisting. The error message provided below,
Exception in thread " STARTING" javax.validation.ConstraintViolationException: Validation failed for classes [mobi.puut.entities.WalletInfo] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=id, rootBeanClass=class mobi.puut.entities.WalletInfo, messageTemplate='{javax.validation.constraints.NotNull.message}'}
ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=currency, rootBeanClass=class mobi.puut.entities.WalletInfo, messageTemplate='{javax.validation.constraints.NotNull.message}'}
]
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:140)
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:80)
at org.hibernate.action.internal.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:197)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:75)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:626)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:280)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:261)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:306)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:189)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:132)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:58)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:780)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:765)
at mobi.puut.database.WalletInfoDao.create(WalletInfoDao.java:62)
at mobi.puut.database.WalletInfoDao$$FastClassBySpringCGLIB$$624213d.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at mobi.puut.database.WalletInfoDao$$EnhancerBySpringCGLIB$$a84b41b3.create(<generated>)
at mobi.puut.services.WalletService.createWalletInfo(WalletService.java:273)
at mobi.puut.services.WalletService.lambda$generateAddress$0(WalletService.java:97)
at mobi.puut.controllers.WalletManager$1.lambda$onSetupCompleted$0(WalletManager.java:109)
at java.lang.Iterable.forEach(Iterable.java:75)
at java.util.Collections$SynchronizedCollection.forEach(Collections.java:2062)
at mobi.puut.controllers.WalletManager$1.onSetupCompleted(WalletManager.java:109)
at org.bitcoinj.kits.WalletAppKit.startUp(WalletAppKit.java:325)
at com.google.common.util.concurrent.AbstractIdleService$2$1.run(AbstractIdleService.java:54)
at com.google.common.util.concurrent.Callables$3.run(Callables.java:95)
The project structure is provided below,

The sample code directed to the error proviced below,
@Transactional(rollbackFor = Exception.class)
public WalletInfo create(String name, String address) {
// create the WalletInfo entity with provided name and address
WalletInfo walletInfo = new WalletInfo();
walletInfo.setAddress(address);
walletInfo.setName(name);
// persist the created instance into the database
sessionFactory.getCurrentSession().persist(walletInfo);
return walletInfo;
}
protected WalletInfo createWalletInfo(final String walletName, final String address) {
return walletInfoDao.create(walletName, address);
}
public synchronized WalletInfo generateAddress(final String walletName, String currencyName) {
// get the WalletInfo entity from the database with the wallet and the currency name
WalletInfo walletInfo = walletInfoDao.getWalletInfoWithWalletNameAndCurrency(walletName, currencyName);
// generate wallet, if the wallet is not
// generated previously
if (walletInfo == null) {
if (genWalletMap.get(walletName) == null) {
logger.info("Wallet name that we are workign on {}", walletName);
final WalletManager walletManager = WalletManager.setupWallet(walletName);
walletManager.addWalletSetupCompletedListener((wallet) -> {
Address address = wallet.currentReceiveAddress();
/*at mobi.puut.services.WalletService.lambda$generateAddress$0(WalletService.java:97) */
WalletInfo newWallet = createWalletInfo(walletName, address.toString());
walletMangersMap.put(newWallet.getId(), walletManager);
genWalletMap.remove(walletName);
});
genWalletMap.put(walletName, walletManager);
}
return walletInfo;
}
return null;
}
private void setupWalletKit(final String walletId) {
File directory = getWalletDirectory(walletId);
// if the seed is not null, that means we are restoring from the backup
bitcoin = new WalletAppKit(networkParameters, directory, WALLET_FILE_NAME) {
@Override
protected void onSetupCompleted() {
// Don't make the user wait for confirmations
// they're sending their own money anyway!!
bitcoin.wallet().allowSpendingUnconfirmedTransactions();
Wallet wallet = bitcoin.wallet();
model.setWallet(wallet);
/* lambda$onSetupCompleted$0(WalletManager.java:109) */
setupCompletedListeners.forEach(listener -> listener.onSetupCompleted(wallet));
}
};
// some code
}
The WalletInfo entity provided,
@Entity
@Table(name = "wallet_info")
public class WalletInfo {
@Id
@Column(name = "id")
// @NotNull
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Column(name = "name")
private String name;
@NotNull
@Column(name = "address")
private String address;
@NotNull
@Column(name = "currency")
private String currency;
public Long getId() {
return id;
}
public WalletInfo(@NotNull String name, @NotNull String address, @NotNull String currency) {
this.name = name;
this.address = address;
this.currency = currency;
}
public WalletInfo(@NotNull String name, @NotNull String address) {
this.name = name;
this.address = address;
}
public WalletInfo() {
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
}
What is the issue here and how to solve it?
The solution provided in the comment is correct, I just want to write it elaborately to help others, especially, who are using the Hibernate newly. The WalletInfo entity matches with the wallet_info table in the MySQL,

Notice that every entity is provided as non-null NN and hence, needs to be matched while persisting in the database.
The walletInfo entity class after the modification,
@Entity
@Table(name = "wallet_info")
public class WalletInfo {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Column(name = "name")
private String name;
@NotNull
@Column(name = "address")
private String address;
@NotNull
@Column(name = "currency")
private String currency;
// getters and setters
// constructors
public WalletInfo(@NotNull String name, @NotNull String address, @NotNull String currency) {
this.name = name;
this.address = address;
this.currency = currency;
}
public WalletInfo(@NotNull String name, @NotNull String address) {
this.name = name;
this.address = address;
}
public WalletInfo() {
}
}
In the database layer, this was the method I was using to persist,
@Transactional(rollbackFor = Exception.class)
public WalletInfo create(String name, String currency, String address) {
// create the WalletInfo entity with provided name and address
WalletInfo walletInfo = new WalletInfo();
walletInfo.setAddress(address);
walletInfo.setName(name);
walletInfo.setCurrency(currency);
// persist the created instance into the database
sessionFactory.getCurrentSession().persist(walletInfo);
return walletInfo;
}
I just added the currecny column and hence, forget to add the
walletInfo.setCurrency(currency) line which made the currency as null earlier and creates the error. I still can make the id null as the this is not an element in the constructor with @NotNull annotation and the entity parameter definition it was also not annotated with @NotNull
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
I hope this will help some people.
In case you are working with lombok, you might have forgotten the @Data-Annotation over your entity class.
The reason why every attribute is null, while it shouldn't be, is that it's simply not possible for spring to write the data into your object, and therefore the exception occurs. No setters, no constructor => no data in your object, so the contents will always be null.
This is a very tricky thing, since you only get an exception when you validate your database entrys, without the Not-Null-Annotation, it just writes null into your fields, if that works out for all of them...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With