Using Spring, Hibernate and JPA to save employee objects to Oracle 12c. Receive No error when running the SpringDataSiebel "main", but actually not save to database.
<context:component-scan base-package="employee"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:#...."/>
<property name="username" value="username"/>
<property name="password" value="password"/>
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="jcgPersistence"/>
<property name="dataSource" ref="dataSource"/>
<property name="persistenceXmlLocation" value="META-INF/persistence.xml"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaDialect" ref="jpaDialect"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<!--prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop-->
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
</props>
</property>
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaDialect" ref="jpaDialect"/>
</bean>
public class SpringDataSiebel {
public SpringDataSiebel() {
super();
}
public static void main(String[] args) {
//SpringDataSiebel s = new SpringDataSiebel();
try {
ApplicationContext context = new ClassPathXmlApplicationContext("META-INF\\spring-config-siebel.xml");
//Fetch the DAO from Spring Bean Factory
EmployeeDao employeeDao = (EmployeeDao) context.getBean("EmployeeDaoImpl");
Employee employee = new Employee("Employee 320");
int id = 330;
employee.setEmployeeId(id);
//Save an employee Object using the configured Data source
employeeDao.save(employee);
System.out.println("Employee Saved with EmployeeId " + employee.getEmployeeId());
//find an object using Primary Key
Employee emp = employeeDao.findByPrimaryKey(employee.getEmployeeId());
System.out.println("Found: " + emp);
Employee emp2 = employeeDao.findByPrimaryKey(1000);
System.out.println("Found: " + emp2);
//Close the ApplicationContext
((ConfigurableApplicationContext) context).close();
} catch (BeansException | SQLException e) {
e.printStackTrace();
}
}
}
public class EmployeeDaoImpl implements EmployeeDao {
public EmployeeDaoImpl() {
super();
}
#PersistenceContext
private EntityManager entityManager;
//#Override
#Transactional
public void save(Employee employee) {
try {
//if (!entityManager.contains(employee)) {
// persist object - add to entity manager
entityManager.persist(employee);
System.out.println("Saving the employee object...");
//}
} catch (Exception ex) {
System.out.println("Something went wrong.");
ex.printStackTrace();
}
}
}
Output:
Saving the employee object...
Employee Saved with EmployeeId 330
Found: null
Found: null
Process exited with exit code 0.
I expect it finds the object "EmployeeId 330"
I have such method
#JmsListener(containerFactory = "jmsListenerContainerFactory", destination = "myQName")
public void rceive(MySerializableObject message) {
log.info("received: {}", message);
}
and such config on xml
<jms:annotation-driven />
<bean id="jmsListenerContainerFactory" class="org.springframework.jms.config.DefaultJmsListenerContainerFactory">
<property name="connectionFactory" ref="pooledConnectionFactory" />
<property name="concurrency" value="3-10" />
</bean>
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${brokerURL}" />
</bean>
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<property name="maxConnections" value="5" />
<property name="maximumActiveSessionPerConnection" value="500" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
<bean id="jmsContainerFactory" class="org.springframework.jms.config.DefaultJmsListenerContainerFactory">
<property name="connectionFactory" ref="pooledConnectionFactory" />
<property name="concurrency" value="3-10" />
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate" p:connectionFactory-ref="pooledConnectionFactory" />
Seems consumer was not created. I can send messages but cannot receive them.
Any idea whats wrong here?
Just tested your config and it works well. Only difference that I make a class with #JmsListener as a <bean> in that context:
<bean class="org.springframework.integration.jms.JmsListenerAnnotationTests$TestService"/>
#ContextConfiguration
#RunWith(SpringJUnit4ClassRunner.class)
#DirtiesContext
public class JmsListenerAnnotationTests {
#Autowired
private JmsTemplate jmsTemplate;
#Autowired
private TestService testService;
#Test
public void test() throws InterruptedException {
this.jmsTemplate.convertAndSend("myQName", "foo");
assertTrue(this.testService.receiveLatch.await(10, TimeUnit.SECONDS));
assertNotNull(this.testService.received);
assertEquals("foo", this.testService.received);
}
public static class TestService {
private CountDownLatch receiveLatch = new CountDownLatch(1);
private Object received;
#JmsListener(containerFactory = "jmsListenerContainerFactory", destination = "myQName")
public void receive(String message) {
this.received = message;
this.receiveLatch.countDown();
}
}
}
<jms:annotation-driven /> makes the #JmsListener infrastructure available, but to force Spring to see those methods your classes should be beans anyway.
For example <component-scan> for the package with #Service classes.
Cheers!
Here is my #Service class whose remind() method is called from the front-end.
#Service
public class EmailManagerImpl implements EmailManager {
private MailSender mailSender;
private SimpleMailMessage templateMessage;
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
public void setTemplateMessage(SimpleMailMessage templateMessage) {
this.templateMessage = templateMessage;
}
#Override
public void remind(Appointment appointment) {
Person patient = appointment.getPatient();
SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage);
msg.setTo(patient.getMail());
msg.setText("Szanowny pacjencie " + patient.getFirstName() + " "
+ patient.getSurname() + " "
+ appointment.toString());
try {
mailSender.send(msg);
} catch (MailException ex) {
// log it and go on
System.err.println(ex.getMessage());
}
}
I am sure that templeMessage and mailSender are injected correctly. After whole process is executed i dont get any error, no exception no debugging info from true. When i try to run one of many demos, it works just fine. The only diffrence is that my application is on Tomcat + i invoke method from bean. Any ideas?
I can follow debug up to the following method from SimpleMailMessage line, later i get message that source is not found:
//---------------------------------------------------------------------
// Implementation of MailSender
//---------------------------------------------------------------------
public void send(SimpleMailMessage simpleMessage) throws MailException {
send(new SimpleMailMessage[] { simpleMessage });
}
My applicationConfig:
<!-- Wysylanie maili -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${mail.host}" />
<property name="port" value="${mail.port}" />
<property name="username" value="${mail.username}" />
<property name="password" value="${mail.password}" />
<property name="protocol" value="smtp" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.ssl.trust">smtp.gmail.com</prop>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.smtps.debug">true</prop>
</props>
</property>
</bean>
<!-- this is a template message that we can pre-load with default state -->
<bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="${mail.username}" />
<property name="subject" value="${mail.subject}" />
</bean>
<bean id="emailManagerImpl" class="com.przychodnia.rejestracja.integration.EmailManagerImpl">
<property name="mailSender"><ref bean="mailSender"/></property>
<property name="templateMessage"><ref bean="templateMessage"/></property>
</bean>
I've read tens of topics and no result.
What the problem:
I can't get current hibernate session in #Transactional method.
EXCEPTION:
Exception in thread "main" org.hibernate.HibernateException: No Session found for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:988)
at name.krestjaninoff.activiti.hello.core.Engine.getHibernateSession(Engine.java:27)
at name.krestjaninoff.activiti.hello.process.CreateClientService.execute(CreateClientService.java:42)
at org.activiti.engine.impl.bpmn.JavaDelegateDelegate.execute(JavaDelegateDelegate.java:48)
at org.activiti.engine.impl.bpmn.JavaDelegateDelegate.execute(JavaDelegateDelegate.java:39)
at org.activiti.engine.impl.bpmn.ClassDelegate.execute(ClassDelegate.java:96)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationActivityExecute.execute(AtomicOperationActivityExecute.java:40)
....
My Code:
#Service
#EnableTransactionManagement(proxyTargetClass=true, mode= AdviceMode.PROXY)
public class CreateClientService {
#Transactional(value="transactionManager", propagation = Propagation.REQUIRED)
public void execute() {
((SessionFactory) applicationContext.getBean("sessionFactory")).getCurrentSession(); //EXCEPTOIN!!!
}
}
My configurations:
<tx:annotation-driven/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" scope="singleton">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan">
<list>
<value>name.krestjaninoff.activiti.hello.db</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL82Dialect</prop>
<!--<prop key="hibernate.hbm2ddl.auto">create</prop>-->
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" scope="singleton">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>
ADDTION: NativeConstructorAccessorImpl class create CreateClientService instance:
#CallerSensitive
public T newInstance(Object ... initargs)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, null, modifiers);
}
}
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
ConstructorAccessor ca = constructorAccessor; // read volatile
if (ca == null) {
ca = acquireConstructorAccessor();
}
return (T) ca.newInstance(initargs);
}ected JavaDelegate javaDelegate;
protected JavaDelegateDelegate() {
}
public JavaDelegateDelegate(JavaDelegate javaDelegate) {
this.javaDelegate = javaDelegate;
}
public void execute(ActivityExecution execution) throws Exception {
execute((DelegateExecution) execution);
performDefaultOutgoingBehavior(execution);
}
public void notify(ExecutionListenerExecution execution) throws Exception {
execute((DelegateExecution) execution);
}
public void execute(DelegateExecution execution) throws Exception {
javaDelegate.execute(execution);
}
}
I am trying to use mybatis spring transaction management
My problem is that the transactions are getting committed even if an exception is thrown.
Relatively new to this, anykind of help is much appreciated.
Following are the code snippets
spring xml configuration
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:Config.properties</value>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.user}"/>
<property name="password" value="${db.pass}"/>
<property name="defaultAutoCommit" value="false" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:Configuration.xml" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSessionTemplate">
<constructor-arg ref="sqlSessionFactory"/>
</bean>
Service class
#Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRED)
public void insertNotes(String noteTypeId,String confidentialValue,String summaryValue,String notes ,String notesId,String noteTypeValue,
String claimNumber,String notepadId,String mode)
{
NotepadExample notepadExample= new NotepadExample();
//to be moved into dao class marked with transaction boundaries
Notepad notepad = new Notepad();
notepad.setAddDate(new Date());
notepad.setAddUser("DummyUser");
if("true".equalsIgnoreCase(confidentialValue))
confidentialValue="Y";
else
confidentialValue="N";
notepad.setConfidentiality(confidentialValue);
Long coverageId=getCoverageId(claimNumber);
notepad.setCoverageId(coverageId);
notepad.setDescription(summaryValue);
notepad.setEditUser("DmyEditUsr");
//notepad.setNotepadId(new Long(4)); //auto sequencing
System.out.println(notes);
notepad.setNotes(notes);
notepad.setNoteType(noteTypeValue); //Do we really need this?
notepad.setNoteTypeId(Long.parseLong(notesId));
if("update".equalsIgnoreCase(mode))
{
notepad.setNotepadId(new Long(notepadId));
notepad.setEditDate(new Date());
notepadMapper.updateByPrimaryKeyWithBLOBs(notepad);
}
else
notepadMapper.insertSelective(notepad);
throw new java.lang.UnsupportedOperationException();
}
Not sure where I am going wrong...
The current call is from the controller as given below
#Controller
public class NotesController {
private static final Logger logger = LoggerFactory
.getLogger(NotesController.class);
#Autowired
private Utils utility;
#Autowired
NotepadService notepadService;
public #ResponseBody List<? extends Object> insertNotes(HttpServletRequest request,
HttpServletResponse response,#RequestParam("noteTypeValue") String noteTypeId,
#RequestParam("confidentialValue")String confidentialValue,
#RequestParam("summaryValue")String summaryValue,
#RequestParam("notes")String notes ,
#RequestParam("notesId")String notesId,
#RequestParam("noteTypeValue")String noteTypeValue,
#RequestParam("claimNumber")String claimNumber,
#RequestParam("notepadId")String notepadId,
#RequestParam("mode")String mode) {
try {
notepadService.insertNotes(noteTypeId, confidentialValue, summaryValue, notes, notesId, noteTypeValue, claimNumber, notepadId, mode);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
I had the same issue. I am also relatively new to spring. But according to me it depends on how you are calling your insertNotes() method. If you are calling it from another local method then it will not work, because spring has no way of know that it is called and to start the transaction.
If you are calling it from a method of another class by using autowired object of the class which contains insertNotes() method, then it should work.
For example
class ABC
{
#Autowired
NotesClass notes;
public void testMethod() {
notes.insertNotes();
}
}
class NotesClass
{
#Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRED)
public void insertNotes(String noteTypeId,
String confidentialValue,
String summaryValue,String notes ,
String notesId,String noteTypeValue,
String claimNumber,
String notepadId,
String mode) {
//Your code
}
}
You can try using transaction template. Remove #Tranasactional annotation from method and following code to xml file.
<bean id="trTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="timeout" value="30"/>
<property name="transactionManager" ref="transactionManager"/>
</bean>
Create object of Trasactiontemplate and call insertNotes from controller like this
#Autowired
private TransactionTemplate transactionTemplate;
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
#Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
try {
insertNotes();
} catch (Exception e) {
transactionStatus.setRollbackOnly();
logger.error("Exception ocurred when calling insertNotes", e);
throw new RuntimeException(e);
}
}
});
Note : You have to make all parameters final before calling insertNotes method