I tried to initialize my database using code bellow
#Component
public class DataBase {
#Transactional
#PostConstruct
public void init() {
Query nativeQuery = entityManager.createNativeQuery("Native SQL Query");
nativeQuery.executeUpdate();
}
}
and I got this runtime exception
Caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1496) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_40]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_40]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_40]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_40]
at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:380) ~[spring-orm-5.0.7.RELEASE.jar:5.0.7.RELEASE]
but injecting DataBase and calling init function is working fine!
#Component
public class TestClass {
#Autowired
private DataBase dataBase;
#PostConstruct
public void test() {
dataBase.init();
}
}
why this is happening!,is this a bug or there is some reason?
Related
I have a Spring Boot app that sends and receives messages on a GCP PubSub queue. Basically I try to store in the DB some of the information that I get in the message. However when I try to commit this information or saveAndFlush() I get the error RollbackException: Error while committing the transaction. If I persists any other information that it's not triggered when the app receives an inbound message it works correctly. If I try saveAndFlush instead of save I get a NullPointerException.
What am I missing?
Thanks.
Error stack
Caused by: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:543)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:633)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:386)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:178)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy153.save(Unknown Source)
at com.sap.service.deployments.DeploymentService.lambda$saveLogs$16(DeploymentService.java:235)
at java.util.Optional.map(Optional.java:215)
at com.sap.service.deployments.DeploymentService.saveLogs(DeploymentService.java:233)
at com.sap.service.deployments.DeploymentService.processDeploymentExecutionResponse(DeploymentService.java:404)
at com.sap.service.deployments.DeploymentService.messageReceiver(DeploymentService.java:245)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:171)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:120)
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper$HandlerMethod.invoke(MessagingMethodInvokerHelper.java:1105)
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.invokeHandlerMethod(MessagingMethodInvokerHelper.java:583)
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:478)
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:356)
at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:108)
... 24 more
Caused by: javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:81)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:104)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:534)
... 54 more
Caused by: java.lang.NullPointerException
at com.sap.config.AuditorAwareImpl.getCurrentAuditor(AuditorAwareImpl.java:13)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
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:344)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:205)
at com.sun.proxy.$Proxy164.getCurrentAuditor(Unknown Source)
at org.springframework.data.auditing.AuditingHandler.lambda$touchAuditor$6(AuditingHandler.java:193)
at java.util.Optional.map(Optional.java:215)
at org.springframework.data.auditing.AuditingHandler.touchAuditor(AuditingHandler.java:191)
at org.springframework.data.auditing.AuditingHandler.lambda$touch$0(AuditingHandler.java:165)
at java.util.Optional.map(Optional.java:215)
at org.springframework.data.auditing.AuditingHandler.touch(AuditingHandler.java:163)
at org.springframework.data.auditing.AuditingHandler.markModified(AuditingHandler.java:143)
at org.springframework.data.jpa.domain.support.AuditingEntityListener.touchForUpdate(AuditingEntityListener.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.hibernate.jpa.event.internal.ListenerCallback.performCallback(ListenerCallback.java:35)
at org.hibernate.jpa.event.internal.CallbackRegistryImpl.callback(CallbackRegistryImpl.java:95)
at org.hibernate.jpa.event.internal.CallbackRegistryImpl.preUpdate(CallbackRegistryImpl.java:69)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.invokeInterceptor(DefaultFlushEntityEventListener.java:366)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.handleInterception(DefaultFlushEntityEventListener.java:348)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.scheduleUpdate(DefaultFlushEntityEventListener.java:299)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:170)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:232)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:92)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1360)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:451)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3210)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2378)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)
... 55 more
AuditorAwareImpl
import org.springframework.data.domain.AuditorAware;
import org.springframework.security.core.context.SecurityContextHolder;
import java.util.Optional;
class AuditorAwareImpl implements AuditorAware<String> {
#Override
public Optional<String> getCurrentAuditor() {
SamlUserDetails userDetails = (SamlUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); //NullPointerExc on this line
return Optional.of(userDetails.getFullname() + " (" + userDetails.getAttribute("uid") + ")");
}
}
This is the configuration of the Inbound PubSub
#Component
public class PubSubInbound {
#Autowired
private DeploymentService deploymentService;
#Bean
public MessageChannel inputMessageChannel() {
return new PublishSubscribeChannel();
}
// Create an inbound channel adapter to listen to the subscription `sub-one` and send
// messages to the input message channel.
#Bean
public PubSubInboundChannelAdapter inboundChannelAdapter(
#Qualifier("inputMessageChannel") MessageChannel messageChannel,
PubSubTemplate pubSubTemplate) {
PubSubInboundChannelAdapter adapter =
new PubSubInboundChannelAdapter(pubSubTemplate, "cerberusSubscription");
adapter.setOutputChannel(messageChannel);
adapter.setAckMode(AckMode.MANUAL);
adapter.setPayloadType(String.class);
return adapter;
}
#Bean
#ServiceActivator(inputChannel = "pubsubInputChannel")
public MessageHandler messageReceiver() {
return message -> {
System.out.println("Message arrived! Payload: " + new String((byte[]) message.getPayload()));
BasicAcknowledgeablePubsubMessage originalMessage =
message.getHeaders().get(GcpPubSubHeaders.ORIGINAL_MESSAGE, BasicAcknowledgeablePubsubMessage.class);
originalMessage.ack();
deploymentService.persistLogs(
Long.parseLong(message.getHeaders().get("deploymentId", String.class)),
new String((byte[]) message.getPayload()));
};
}
}
DeploymentService
#Service
public class DeploymentService {
#Autowired
private DeploymentRepository deploymentRepository;
....
public Optional<Deployment> persistLogs(Long deploymentId, String logs){
Optional<Deployment> deploymentOpt = deploymentRepository.findById(deploymentId);
return deploymentOpt.map(deployment -> {
deployment.setLogs(logs);
return deploymentRepository.save(deployment); //ERROR HERE
});
}
....
DeploymentRepository
#Repository
public interface DeploymentRepository extends JpaRepository<Deployment, Long> { }
Solved.
SecurityContextHolder.getContext().getAuthentication()
was null when the message is coming from the GCP PubSub. Reworking the getCurrentAuditor did the trick.
#Override
public Optional<String> getCurrentAuditor() {
if(SecurityContextHolder.getContext().getAuthentication()!=null){
SamlUserDetails userDetails = (SamlUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return Optional.of(userDetails.getFullname() + " (" + userDetails.getAttribute("uid") + ")");
}else return Optional.empty();
}
After a few days on trying to figure out my problem, I am thoroughly confused. Here is what I am doing. I am running a Spring Boot project using JPA. I have gotten the JDBCTemplate solution working for one table in a PostgreSQL database. I have tested it with no problem. Now I moved to the major portion of the project with six tables. I chose JPA as there is mostly CRUD operations.
When I build and test using SpringBoot, I am getting the below two errors for my AcceptanceCriteriaTest. I see Spring cannot initialize the Abstract which leads to believer I do not have my annotations right. The other error is I ca not find my Persistence Unit identified.
Any suggestions would be greatly appreciated.
Thanks,
Russ
java.lang.NoClassDefFoundError: Could not initialize class org.company.me.batch.test.eao.AbstractJPATest
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:33)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:114)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:57)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:66)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:109)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:147)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:129)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
And this is the second error from the test:
java.lang.ExceptionInInitializerError
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:114)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:57)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:66)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:109)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:147)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:129)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.persistence.PersistenceException: No Persistence provider for EntityManager named jpaReqChgPU
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:61)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
at org.company.me.batch.test.eao.AbstractJPATest.<clinit>(AbstractJPATest.java:25)
... 41 more
Here is how I configured the table using JPA:
#Entity
#Table(name="accCriteria_tbl", schema="iaReqChanges")
#SequenceGenerator(name="AcceptCritera_SEQ_GEN", schema="iaReqChanges", sequenceName = "accCriteria_tbl_accCri_id_seq", initialValue = 1, allocationSize = 1)
public class AcceptanceCriteria implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator="AcceptCritera_SEQ_GEN")
#Column(name="accCri_id", updatable = false)
private Long accCri_id;
Now I want to test my Entity. This is my test case:
#RunWith(SpringRunner.class)
#PropertySource(name="X", value={"classpath:/applicationConfig.properties"})
#SpringBootTest(classes = ApplicationConfig.class)
public class AcceptCriteriaTest extends AbstractJPATest {
#Test
public void testCreateAcceptCriteria(){
String accCriteriaAction="Give Mary a little Lamb";
String accCriteriaControl="Mary's lamb must be white as snow";
String accAcceptanceCriteria="Does Mary have a little lamb. IS is white as snow?";
String busRequirement="Mary must be happy with her lamb that is white as snow";
Timestamp lastModified = new java.sql.Timestamp(Calendar.getInstance().getTime().getTime());
AcceptanceCriteria acceptCriteria = new AcceptanceCriteria();
acceptCriteria.setAccAccptCriteria(accAcceptanceCriteria);
acceptCriteria.setAccAction(accCriteriaAction);
acceptCriteria.setBusRequirement(busRequirement);
acceptCriteria.setLastModified(lastModified);
AbstractJPATest.entityManager.persist(acceptCriteria);
AcceptanceCriteria acceptCriteria2 = AbstractJPATest.entityManager.find(AcceptanceCriteria.class, acceptCriteria);
assertTrue((acceptCriteria.getAccAction().equals(accCriteriaAction)));
}
This is my Abstract Class:
public abstract class AbstractJPATest extends TestCase {
static final EntityManagerFactory EMF = Persistence.createEntityManagerFactory("jpaReqChgPU");
//#PersistenceContext
//protected static EntityManager em = null;
#PersistenceContext
protected static TestEntityManager entityManager = new TestEntityManager(EMF);
This is my ApplicationConfig class:
#Configuration
#ComponentScan
#EnableTransactionManagement
#EnableConfigurationProperties(LiquibaseProperties.class)
#PropertySource(name="X", value={"classpath:/applicationConfig.properties"})
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
#SpringBootApplication
public class ApplicationConfig {
private static final Logger slf4jLogger = LoggerFactory.getLogger(ApplicationConfig.class);
#Autowired
LiquibaseProperties properties;
#Autowired
private Environment env;
/* Data Source configuration is in applicationConfig.properties file */
#Autowired
private DataSource dataSource;
#Value("${init-db:false}")
private String initDatabase;
#Bean
public SpringLiquibase liquibase() {
SpringLiquibase liquibase = new SpringLiquibase();
properties.setChangeLog("classpath:/db/changelog/postgres-changelog-master.xml");
liquibase.setChangeLog(this.properties.getChangeLog());
liquibase.setContexts(this.properties.getContexts());
liquibase.setDataSource(this.dataSource);
liquibase.setDefaultSchema(this.properties.getDefaultSchema());
liquibase.setDropFirst(this.properties.isDropFirst());
liquibase.setShouldRun(this.properties.isEnabled());
return liquibase;
}
#Bean
public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
/* This is used for the SQLDAO*/
#Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource)
{
return new JdbcTemplate(dataSource);
}
/*
#Bean(name="PlaformTransactionManager")
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
*/
#Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
entityManagerFactory.setDataSource(dataSource);
entityManagerFactory.setPersistenceUnitName("jpaReqChgPU");
entityManagerFactory.setJpaDialect(jpaDialect());
entityManagerFactory.setJpaVendorAdapter(jpaVendorAdapter());
entityManagerFactory.setPackagesToScan("org.itaa.ia.batch");
entityManagerFactory.setJpaPropertyMap(hibernateJpaProperties());
slf4jLogger.debug("emf", entityManagerFactory.toString());
return entityManagerFactory;
}
#Bean(name = "jpaVendorAdapter")
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.PostgreSQLDialect");
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setShowSql(true);
return vendorAdapter;
}
#Bean(name = "jpaDialect")
public JpaDialect jpaDialect() {
return new HibernateJpaDialect();
}
#Bean(name = "persistenceExceptionTranslation")
PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
private Map<String, ?> hibernateJpaProperties() {
HashMap<String, String> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto", "create");
//properties.put("hibernate.show_sql", "false");
properties.put("hibernate.format_sql", "false");
properties.put("hibernate.hbm2ddl.import_files", "insert-data.sql");
properties.put("hibernate.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy");
properties.put("hibernate.c3p0.min_size", "2");
properties.put("hibernate.c3p0.max_size", "5");
properties.put("hibernate.c3p0.timeout", "300"); // 5mins
return properties;
}
#Bean(name="jpaTransManager")
public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
//org.springframework.orm.jpa.JpaTransactionManager
//JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(emf);
jpaTransactionManager.setPersistenceUnitName("jpaReqChgPU");
jpaTransactionManager.setDataSource(dataSource);
jpaTransactionManager.setJpaDialect(jpaDialect());
jpaTransactionManager.setJpaPropertyMap(hibernateJpaProperties());
//jpaTransactionManager.setEntityManagerFactory(emf);
return jpaTransactionManager;
}
public static void main(String[] args) throws Exception {
SpringApplication springApplication = new SpringApplication();
springApplication.setWebEnvironment(false);
SpringApplication.run(ApplicationConfig.class, args);
}
I am using Spring Boot and configured my Application like this:
#Configuration
#EnableAutoConfiguration
#EnableTransactionManagement
#ComponentScan
#EntityScan("ch.xy.model")
public class Application {
#Autowired
private ImportDAO importDao;
}
ImportDAO looks like that:
#Repository
public class ImportDAO {
#PersistenceContext
private EntityManager em;
#Transactional
void removeTempoAccounts() {
Query q = em.createQuery("DELETE FROM TempoAccount t WHERE t.manual = false");
q.executeUpdate();
}
}
But when removeTempoAcconts is executed I get:
Exception in thread "main" javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:360)
at com.sun.proxy.$Proxy49.executeUpdate(Unknown Source)
at ch.post.pf.jira.tempocats.pspimport.ImportDAO.removeTempoAccounts(ImportDAO.java:95)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:711)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
at ch.post.pf.jira.tempocats.pspimport.ImportDAO$$EnhancerBySpringCGLIB$$1883cf82.removeTempoAccounts(<generated>)
at ch.post.pf.jira.tempocats.pspimport.PspImport.run(PspImport.java:32)
at ch.post.pf.jira.tempocats.pspimport.Application.main(Application.java:20)
What's wrong with my configuration?
#Transactional
void removeTempoAccounts() {
Method had default visibility. Therefore the proxy mechanism was not active!
After changing to public everthing works as expected!
Try to use the #Transactional annotation from Spring package
like #org.springframework.transaction.annotation.Transactional
Then it should work
I'm using spring mvc.
I want to test my service with Junit.
I want to test the inclusion of a new user
I write the class test:
#ContextConfiguration("/dispatcher-servlet.xml")
public class ServizioUtenteTest {
#Autowired
private ServizioUtente servizioutente;
#Test
public void testAggiungiUtente() {
//fail("Not yet implemented");
Utente utente=new Docente();
utente.setCognome("Professore");
utente.setPassword("tetxts");
utente.setUsername("xxxx");
servizioutente.aggiungiUtente(utente);
}
#Test
}
When I run the test I get:
java.lang.NullPointerException
at org.rol.test.ServizioUtenteTest.testAggiungiUtente(ServizioUtenteTest.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
....)
The error is thrown on the line, why?
help me!?
You are missing SpringJUnit4ClassRunner:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("/dispatcher-servlet.xml")
public class ServizioUtenteTest {
//...
See also
Creating unitary tests in Spring 3
11. Testing
I am working on a project that uses Spring and Hibernate. I have an abstract DAO that contains SessionFactory. I need to mock SessionFactory or Session for my unit test. But I have not been successful so far. Below is the code. Anyone has any idea? Thank you.
Here is my AbstractDAO
public abstract class AbstractDAO {
protected JdbcTemplate jdbcTemplate;
protected SessionFactory sessionFactory;
protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;
...
#Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}}
And here is my ConcreteDAO
public class LoginDAO extends AbstractDAO implements InitializingBean {
...
public User getLoggedinUserByUserid(Long userid){
log.info("in getLoggedinUserByUserid");
User result = null;
Session session = sessionFactory.openSession();
try {
session.beginTransaction();
result = (User) session.get(User.class, userid);
session.getTransaction().rollback();
session.close();
} catch (Exception e) {
log.error(e,e);
session.getTransaction().rollback();
session.close();
}
return result;
}
...}
and here is my test class
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "LoginDAOTest-context.xml" })
#PrepareForTest({SessionFactory.class, Session.class, Transaction.class})
public class LoginDAOTest2 extends BaseDAO {
private static final Logger log = Logger.getLogger(LoginDAOTest2.class);
#Rule
public PowerMockRule rule = new PowerMockRule();
private LoginDAO loginDAO = new LoginDAO();
private SessionFactory mockedSessionFactory;
private Session mockedSession;
private Transaction mockedTransaction;
#Autowired
public void setSessionFactory(SessionFactory sessionFactoryCore) {
mockedSessionFactory = PowerMockito.mock( sessionFactoryCore.getClass());
mockedSession = PowerMockito.mock(Session.class);
PowerMockito.doReturn(mockedSession).when(mockedSessionFactory).openSession();
PowerMockito.doReturn(mockedTransaction).when(mockedSession).beginTransaction();
loginDAO.setSessionFactory(this.mockedSessionFactory);
}
#Test
public void shouldRollbackInGetLoggedinUserByUseridWhenSessionThrowsException() {
// Given
PowerMockito.doThrow(new Exception()).when(mockedSession).get(User.class, 12L);
// When
loginDAO.getLoggedinUserByUserid(12L);
// Then
verify(mockedTransaction, times(1)).rollback();
}
}
and here is the result of junit.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.aeon.ps.dao.LoginDAOTest2': Injection of autowired dependencies failed; nested exception is java.lang.NoClassDefFoundError: org/mockito/internal/MockitoInvocationHandler
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:374)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.NoClassDefFoundError: org/mockito/internal/MockitoInvocationHandler
at org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:138)
at com.aeon.ps.dao.LoginDAOTest2.setSessionFactory(LoginDAOTest2.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
... 26 more
Caused by: java.lang.ClassNotFoundException: org.mockito.internal.MockitoInvocationHandler
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 35 more
Why don't do this :
#Before
public void setUp() {
mockedSessionFactory = Mockito.mock(SessionFactory.class);
mockedSession = Mockito.mock(Session.class);
mockedTransaction = Mockito.mock(Transaction.class);
Mockito.when(mockedSessionFactory.openSession()).thenReturn(mockedSession);
Mockito.when(mockedSession.beginTransaction()).thenReturn(mockedTransaction);
loginDAO.setSessionFactory(this.mockedSessionFactory);
}
instead of :
#Autowired
public void setSessionFactory(SessionFactory sessionFactoryCore) {
mockedSessionFactory = PowerMockito.mock( sessionFactoryCore.getClass());
mockedSession = PowerMockito.mock(Session.class);
PowerMockito.doReturn(mockedSession).when(mockedSessionFactory).openSession();
PowerMockito.doReturn(mockedTransaction).when(mockedSession).beginTransaction();
loginDAO.setSessionFactory(this.mockedSessionFactory);
}
In addition, it allows you to not use powermock.
Interesting part is here :
Caused by: java.lang.NoClassDefFoundError: org/mockito/internal/MockitoInvocationHandler
at org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:138)
at com.aeon.ps.dao.LoginDAOTest2.setSessionFactory(LoginDAOTest2.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
... 26 more
It means that powermock is using an internal class that is not available in the mockito distribution your are using.
From that information I gather you are using Mockito 1.9.5-rc1, with some other recent Powermock release. As of now, Johan din't released a newer version of Powermock that take care of the changes that were made in Mockito 1.9.5-rc1.
These refactoring changes in Mockito were made to help the introduction of the MockMaker API, which allows a third party to provide his own mock factory, bytecode engine or else to create mocks.
See the documentation here : http://docs.mockito.googlecode.com/hg/1.9.5-rc1/org/mockito/Mockito.html
So for now, you should use Mockito 1.9.0 if you are using Powermock.