oracle spring transaction not rolling back - transactional

<bean id = "transactionManager"
class = "org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg name = "dataSource"
ref="dataSource">
</constructor-arg>
</bean>
<tx:annotation-driven transaction-manager = "transactionManager"/>
<bean id = "dataSource"
class = "org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name = "driverClassName"
value = "oracle.jdbc.OracleDriver" />
<property name = "url"
value = "jdbc:oracle:thin:#localhost:1521/orcl" />
<property name = "username"
value = "sys as SYSDBA" />
<property name = "password"
value = "sys" />
</bean>
<bean id = "namedParameterJdbcTemplate"
class = "org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg name = "dataSource"
ref = "dataSource">
</constructor-arg>
</bean>
#Component
#Service
public class TestService {
#Autowired
public TestDao testDao;
#Transactional(value = "transactionManager", propagation = Propagation.REQUIRED)
public String insert(){
//testDao.insertUser(107, "Sec");
testDao.insertUser(101, "Sec");
testDao.insertUser(100, "Sec");
return "ok";
}
}
#transactional rollback for exception.class not working.
Got java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint but still not rolling back. First DAO is executing.

Related

How to import DataSource created in #Configuration java class and use in config.xml as reference

I have my datasource in below class. Is there any way I can use that in config.xml?
I am getting an Error creating bean with name 'cmsTemplate' defined in file: cannot resolve reference bean 'contentDataSource' while setting constructor argument.
JdbcConfiguration.java
#Configuration
public class JdbcConfiguration{
#Value("$comContent.url")
private String dbUrl;
#Value("$comContent.dbUser")
private String dbUser;
#Value("$comContent.dbPass")
private String dbPass;
//rest of the properties
#Bean
#Primary
public DataSource contentDataSource() throws SQLException {
//code
}
}
config.xml
<bean id="cmsTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-args type="javax.sql.DataSource">
<ref bean="contentDataSource"/>
</constructor-args>
<property name="fetchSize" value="{systemProperties['jdbcFetchSize']}" />
</bean>
//Need to create datasource before spring context is getting created. Previously it was like below commented code.
<!-- <bean id="contentDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/comContent</value>
</property>
</bean> -->

Mockito doesn't mock in spring mvc controller test

I have controller
#Controller
public class AuthorController {
#Autowired
private AuthorDAO authorDao;
#RequestMapping("/authors")
public String showAuthor(#RequestParam String name, ModelMap model) {
Author author = authorDao.findByName(name);
model.addAttribute("author", author);
return "authors";
}
}
I wrote test for it
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:test-application-context.xml"})
public class AuthorControllerTest {
private static final String JACK_C = "Jack C.";
#Autowired
AuthorController controller;
#Test
public void testShowAuthor() {
Author expectedAuthor = new Author();
AuthorDAO daoMock = mock(AuthorDAO.class);
when(daoMock.findByName(JACK_C)).thenReturn(expectedAuthor);
ModelMap model = new ModelMap();
String view = controller.showAuthor(JACK_C, model);
assertEquals("View name is incorrect","authors", view);
assertSame(expectedAuthor, model.get("author"));
verify(daoMock).findByName(JACK_C);
}
}
test-application-context.xml:
<context:annotation-config />
<context:component-scan base-package="com.github.futu" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property
name="url" value="jdbc:mysql://localhost:3306/blog" /> <property name="username"
value="blogger" /> <property name="password" value="blogger" /> </bean>
<bean id="com.github.futu.dao.AuthorDAO" class="com.github.futu.dao.impl.AuthorDAOXml"/>
<bean id="com.github.futu.dao.PostDAO" class="com.github.futu.dao.impl.PostDAOXml" />
<bean id="validator" class="com.github.futu.validator.PostValidator" />
But real dao is called. What have I missed?
You're creating a mock here
AuthorDAO daoMock = mock(AuthorDAO.class);
that is completely unrelated to your controller injected into your test class
#Autowired
AuthorController controller;
Of course the autowired AuthorDao target is going to come from your XML configuration
#Autowired
private AuthorDAO authorDao;
Ideally you would change your XML configuration only produce a #Controller bean and add a setter to it to set the AuthorDao from within the test, using your mock.

Spring mvc not able to read messages.properties file

I am trying to use custom validation error messages by using properties file. I have placed messages.properties file in web content/web-inf/ folder.
NonEmpty.batchDomain.batchName=Invalid message 2.
My applicationContext file is :
<context:component-scan base-package="com.coaching.controller" />
<!-- Enable annotation driven controllers, validation etc... -->
<mvc:annotation-driven />
<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views
directory -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<mvc:default-servlet-handler />
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/messages" />
</bean>
And my controller is :
#RequestMapping(method = RequestMethod.POST)
public ModelAndView addBatch(
#Valid #ModelAttribute("batchDomain") BatchDomain batchDomain,
BindingResult result, HttpServletRequest request,
HttpServletResponse response) throws Exception {
try {
if (result.hasErrors()) {
ModelAndView modelAndView = new ModelAndView("newBatch");
return modelAndView;
}
}
BatchDomain is :
public class BatchDomain {
#NotNull
#NotEmpty
#Size(min = 1, max = 100)
private String batchName;
#Min(1)
#Max(1000)
private int strength;
}
As far as I have seen in google, I am following the correct approach. So, what can be the reason behind this issue?
You may try to put file "messages.properties" in /src/main/resource directory.

MappingJacksonJsonView return top-level json object

I converted to controller to use ContentNegotiatingViewResolver instead of MessageConverters to support multiple output types. With json, I am using MappingJacksonJsonView:
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="mediaTypes">
<map>
<entry key="html" value="text/html"/>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean class="org.springframework.oxm.xstream.XStreamMarshaller" />
</constructor-arg>
</bean>
</list>
</property>
<property name="ignoreAcceptHeader" value="true" />
<property name="defaultContentType" value="application/json" />
</bean>
With the following controller logic:
#RequestMapping(value = "/id/{id}", method = RequestMethod.GET)
public ModelAndView getById(#PathVariable (value="id") String id) {
MyObject ret = doGetById(id);
ModelAndView modelAndView = new ModelAndView("common/single");
modelAndView.addObject("myObject", ret);
return modelAndView;
}
The json return when I access /id/1234.json is something like:
{
myObject: {
field1:"abc",
field2:"efg"
}
}
Is there a way for my to set myObject as the top level node for the result so it look like this instead:
{
field1:"abc",
field2:"efg"
}
What's happening is Spring MVC is taking the ModelAndView and serializing it to JSON. Since a ModelAndView just looks like a map, and in this case, you only have one entry in the map with a key name of myObject, that's what the JSON response looks at. In order to get just your object, you need to return just your object instead of a ModelAndView and let Jackson serialize your object to JSON.
Rather than returning a ModelAndView, return a MyObject and annotate the method with #ResponseBody, so your controller method becomes
#RequestMapping(value="/id/{id}", method=RequestMethod.GET, produces="application/json")
public #ResponeBody MyObject getById(#PathVariable (value="id") String id) {
return doGetById(id);
}
I faced same issue and following solution works for me.
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<property name="prefixJson" value="true" />
</bean>
You should be able to remove the outer node by using MappingJacksonJsonView.setExtractValueFromSingleKeyModel(true):
Set whether to serialize models containing a single attribute as a map
or whether to extract the single value from the model and serialize it
directly.
The effect of setting this flag is similar to using
MappingJacksonHttpMessageConverter with an #ResponseBody
request-handling method.
For example:
private final MappingJacksonJsonView view = new MappingJacksonJsonView();
public MyController() {
view.setExtractValueFromSingleKeyModel(true);
}
#RequestMapping(value = "/id/{id}", method = RequestMethod.GET)
public ModelAndView getById(#PathVariable (value="id") String id) {
MyObject ret = doGetById(id);
ModelAndView modelAndView = new ModelAndView();
modelAndView.setView(this.view);
modelAndView.addObject("myObject", ret);
return modelAndView;
}
This should also work if you prefer to do it via configuration:
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<property name="extractValueFromSingleKeyModel" value="true" />
</bean>

spring-mvc: error mapping url for form controller

i have a problem with spring mvc
my spring bean
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean
class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
<bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="welcome.htm">welcomeController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean name="welcomeController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="welcome" />
<bean name="/bscList.htm" class="cbs.web.BscController">
<property name="bscDao" ref="myBscDao" />
</bean>
<bean name="/bscForm.htm" class="cbs.web.BscFormController">
<property name="commandName" value="bsc"/>
<property name="commandClass" value="cbs.domain.Bsc"/>
<property name="formView" value="bscForm"/>
<property name="successView" value="bscList.htm"/>
<property name="bscDao" ref="myBscDao"/>
</bean>
</beans>
my form controller
public class BscFormController extends SimpleFormController {
private static Logger log = Logger.getLogger(BscController.class);
private BscDao bscDao;
public void setBscDao(BscDao bscDao) {
this.bscDao = bscDao;
}
protected Object formBackingObject(HttpServletRequest request)
throws Exception {
String id = request.getParameter("id");
if (!StringUtils.isBlank(id)) {
return bscDao.get(new Integer(id));
}
return new Bsc();
}
public ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors)
throws Exception {
log.debug("entering 'onSubmit' method...");
Bsc bsc = (Bsc) command;
String success = getSuccessView();
if (request.getParameter("delete") != null) {
bscDao.remove(bsc.getId());
} else {
bscDao.save(bsc);
}
return new ModelAndView(success);
}
}
my problem:
when I access /bscList.htm, it's display list of bsc (bscList.jsp template),
but when I access /bscForm.htm, it's still display bsc's list, not show my form (bscForm.jsp template)
I have test with some simple controller:
controller implement org.springframework.web.servlet.mvc.Controller, evething run fine
controller extends SimpleFormController, map error:
No mapping found for HTTP request with URI [/cbs/testform.htm] in DispatcherServlet with name 'dispatcher'
when i use HandlerMapping ControllerClassNameHandlerMapping, all request URL '/bsc*' will map to BscController (/bscForm.htm will not map to BscFormController)

Resources