i am learning Parameterized Junit test cases, i am trying to get user by Id. while performing this i am getting error:
"Java.lang.IllegelArgumentException: Wrong number of arguments."
please tell me what is the wrong with this code.
#RunWith(Parameterized.class)
public class UserTestCases {
#Mock
UserRepository userRepository;
#InjectMocks
private UserServiceImpl userService;
private User user;
private User expectedUser;
public UserTestCases(User user, User expectedUser) {
super();
this.user = user;
this.expectedUser = expectedUser;
}
#Parameters
public static Collection input() {
User u1=new User(1, "india", "shiva");
User u2=new User(2, "india", "shiva");
User u3=new User(3, "india", "shiva");
return Arrays.asList(new Object[][] {{new User(1L, "india", "shiva"), u1}, {new User(2, "india", "shiva"), u2},{new User(3, "india", "shiva"), u3}});
}
#Test
public void getUserByIdtest() {
when(userRepository.findOne(user.getId())).thenReturn(user);
User result=userService.findById(user.getId());
assertEquals(user.getCountry(), expectedUser.getCountry());
assertEquals(user.getName(), expectedUser.getName());
}
}
Thanks in advance
If you are learning to use JUnit, maybe you can try the last version: JUnit5.
This last version make it easier to compose external features such as mocking, generating test cases, loading Spring beans etc.
Moreover, it as built-in support for parameterized methods (tests), whereas JUnit4 as only parameterized classes (test suites) and was needed JUnitParams and its Runner to support parameterized tests.
Your test can be written like this in JUnit5:
#ExtendWith(MockitoExtension.class)
class UserTestCases {
#Mock UserRepository userRepository;
#InjectMocks UserServiceImpl userService;
#ParameterizedTest
#MethodSource("input")
void getUserByIdtest(User user, User expectedUser) {
when(userRepository.findOne(user.getId())).thenReturn(user);
User result = userService.findById(user.getId());
assertEquals(user.getCountry(), expectedUser.getCountry());
assertEquals(user.getName(), expectedUser.getName());
}
static Stream<Arguments> input() {
return Stream.of(
// static method of Arguments
arguments(
new User(1, "india", "shiva"),
new User(1L, "india", "shiva")),
arguments(
new User(2, "india", "shiva"),
new User(2L, "india", "shiva")),
arguments(
new User(3, "india", "shiva"),
new User(3L, "india", "shiva")),
);
}
}
However, this test is just about delegation from UserServiceImpl to UserRepository, so you do not need parameterized tests here.
The only test that is needed if you want to check delegation (without mapping it seems) is something like:
class UserTestCases {
#Mock UserRepository userRepository;
#InjectMocks UserServiceImpl userService;
#Test
void getUserByIdtest() {
User user = mock(User.class);
when(userRepository.findOne(any())).thenReturn(user);
assertEquals(userService.findById(1L), user);
}
}
Such a test uses JUnit5 and Mockito libraries.
If you are using Maven, your POM can be something like:
<properties>
<junit-jupiter.version>5.3.1</junit-jupiter.version>
<mockito.version>2.23.0</mockito.version>
<surefire-plugin.version>2.22.1</surefire-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</test>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
</plugin>
</plugins>
</build>
Hope this helps !
Related
I am using the spring boot version 2.3.3, below is my pom.xml.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.group</groupId>
<artifactId>artifact</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>project</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20190722</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I have a custom class/model.
public class Summary {
// attributes
//constructor
// getters/setters for each attributes
}
Its repository (interface and implementation)
public interface SummaryRepository {
List<Summary> getSummaryData(Date date);
}
#Repository
#Transactional
public class SummaryRepositoryImpl implements SummaryRepository {
#PersistenceContext
EntityManager entityManager;
#Override
public List<Summary> getSummaryData(Date date) {
// Implementation
}
}
In the controller, I am having the following code:
#RestController
public class SummaryController {
#Autowired
private SummaryRepository summaryRepository;
#RequestMapping(
value ="/summary-data",
method = RequestMethod.POST,
consumes = "application/json",
produces = MediaType.APPLICATION_JSON_VALUE
)
public ResponseEntity<List<Summary>> getSummaryData(#RequestBody RequestConfig requestConfig ) {
String dateStr = requestConfig.getDate();
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
try {
date = formatter.parse(dateStr);
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
}
// Some logic
List<Summary> summaries = summaryRepository.getSummaryData(date);
if (summaries.size() > 0 ) {
return ResponseEntity.ok(summaries);
} else {
return ResponseEntity.notFound().build();
}
}
}
When I go to postman and send the POST request to above, I get the output as below:
[["2020-07-31", <values>],["2020-07-31",<values2>],["2020-07-31", <values3>],["2020-07-31",<values4>]]
i.e. literal list of object.
I am looking to get it in Json; something like:
[
{ "date": "2020-07-31", "attr2": "value2", "attr3": "value3" },
{ "date": "2020-07-31", "attr2": "value21", "attr3": "value31" },
{ "date": "2020-07-31", "attr2": "value12", "attr3": "value13" },
{ "date": "2020-07-31", "attr2": "value2", "attr3": "value3" }
]
i.e. "date", "attr2", etc are my attributes of the Summary (already defined with getters/setters).
What is missing here?
--------UPDATE---------
Based on the below response I have my SummaryResponse class.
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
public class SummaryResponse {
#JsonProperty(value = "summary", required = true)
List<Summary> summaryList;
public SummaryResponse() {
}
public List<Summary> getSummaryList() {
return summaryList;
}
public void setSummaryList(List<Summary> summaryList) {
this.summaryList = summaryList;
}
}
I changed my controller logic to return this object.
#RequestMapping(
value ="/summary-data",
method = RequestMethod.POST,
consumes = "application/json"
)
public ResponseEntity<SummaryResponse> getSummaryData(#RequestBody RequestConfig requestConfig ) {
// Logic
List<Summary> summaries = summaryRepository.getSummaryData(date);
SummaryResponse summaryResponse = new SummaryResponse();
summaryResponse.setSummaryList(summaries);
if (summaries.size() > 0 ) {
return new ResponseEntity<>(summaryResponse, HttpStatus.OK);
} else {
return ResponseEntity.notFound().build();
}
}
Still I am not getting the JSON output. It is still Array of attributes.
{"summary":[["2020-07-31","attr2_value","attr3_value", null, "attr5_value"] ,["2020-07-31","attr2_value","attr3_value","attr4_value","attr5_value"]]}
What exactly is the issue here?
I am looking something like below:
[
{ "date": "2020-07-31", "attr2": "attr2_value", "attr3": "attr3_value", "attr4", null, "attr5": "attr5_value" },
{ "date": "2020-07-31", "attr2": "attr2_value", "attr3": "attr3_value", "attr4", "attr4_value", "attr5": "attr5_value" }
]
------------------UPDATE 2: Found the issue.----------------
Thanks for the hints, I got the issue.
In my Repository, I am using the native query where class is not entity.
List<Summary> summaryList = query.getResultList();
return summaryList;
Although I am taking the result in summaryList, it is actually a Object[] and not List. (Didn't knew this, new to spring boot and JPA).
So although my Controller is passing this (summaryList) to response it is actually a Object[].
My Summary Class is not a Entity (does not come from table or has identity), so changed my repository method:
List<Object> result = (List<Object>) query.getResultList();
Iterator it = result.iterator();
List<Summary> summaryList = new ArrayList<>();
while (it.hasNext()) {
Object[] row = (Object[]) it.next();
Summary summary = new Summary();
summary.setDate( (Date) row[0]);
summary.setName(String.valueOf(row[1]));
summary.setAccount(String.valueOf(row[2]));
...
...
// and so on
summaryList.add(summary);
}
Finally it is working as expected.
There are multiple ways to achieve this. You could write your own response class and add Jackson annotations. You need to do the same for the Summary class.
public class MyResponse {
#JsonProperty(value = "summary", required = true)
List<Summary> summaryList;
public List<Summary> getSummaryList() {
return summaryList;
}
public void setSummaryList(List<Summary> summaryList) {
this.summaryList = summaryList;
}
}
Make sure you have the Jackson dependency:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
Check your Summary class.
Based on the http responses you shared, the issue should be there - or at least you should be able to fix it there by adding jackson annotations.
You use a Date type inside your Summary class, which acts strange. If you use regular Date (import java.util.Date;) your response JSON response should look like this:
{
"id": "1",
"name": "Ball",
"date": "2020-10-09T19:05:17.189+00:00"
}
But your JSON has a short String representation of the date: "date": "2020-07-31".
So maybe inside your Summary class you import a Date class, which is not properly supported by Jackson.
Try to remove the date attribute and then check again your JSON response.
Instead of returning the List, just return one element of this List.
This should help you to find your problem.
I wrote this German blog post about handling JSON with Jackson in a Spring RestController - as it is the default in Spring Boot:
https://agile-coding.blogspot.com/2020/10/rest-json-apis-in-java-leicht-gemacht.html
This code works in Spring 5. But my company requires Spring 4.
In Spring 4, login works fine with inMemoryAuthentication. But when I added jdbc logic (c3p0, MySQL dependency && add DataSource code && JDBC connection, c3p0 Connection pool .properties file); server runs, login page opens, but authentication fails (Username/Password is incorrect).
Here is the package Structure
Here is .properties file location and code.
This is the Configuration class
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.nike.mycoolwebapp")
#PropertySource("classpath:persistence-mysql.properties")
public class AppConfig {
// set up variable to hold the properties. One can use spring helper classes or use #Autowired
#Autowired
private Environment env; // will hold the data read from the properties file
// set up a logger for diagnostics
private Logger logger = Logger.getLogger(getClass().getName());
// define a bean for ViewResolver
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
// define a bean for our security datasource
#Bean
public DataSource securityDataSource() {
// create a connection pool
ComboPooledDataSource securityDatasource
= new ComboPooledDataSource();
// set the jdbc driver
try {
securityDatasource.setDriverClass(env.getProperty("jdbc.driver"));
} catch (PropertyVetoException exc) {
// I'm wrapping this exception as runtime exception. It's unchecked and throwing that,
// so, at least the system knows if something goes wrong, or if there's a problem
throw new RuntimeException(exc);
}
// log the connection props
// just for sanity's sake. if it's reading from properties file
logger.info(">>> jdbc.url= " + env.getProperty("jdbc.url"));
logger.info(">>> jdbc.user= " + env.getProperty("jdbc.user"));
logger.info(">>> jdbc.password= " + env.getProperty("jdbc.password"));
// set the database connection props
securityDatasource.setJdbcUrl(env.getProperty("jdbc.url"));
securityDatasource.setUser(env.getProperty("jdbc.user"));
securityDatasource.setPassword(env.getProperty("jdbc.password"));
// set the connection pool props
securityDatasource.setInitialPoolSize(
getIntProperty("connection.pool.initialPoolSize"));
securityDatasource.setMinPoolSize(
getIntProperty("connection.pool.minPoolSize"));
securityDatasource.setMaxPoolSize(
getIntProperty("connection.pool.maxPoolSize"));
securityDatasource.setMaxIdleTime(
getIntProperty("connection.pool.maxIdleTime"));
return securityDatasource;
}
// need a helper method
// read environment property and convert to int
private int getIntProperty(String propName) {
String propValue = env.getProperty(propName);
// now convert to int
int intPropValue = Integer.parseInt(propValue);
return intPropValue;
}
}
Here is Security Config
#Configuration
#EnableWebSecurity
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
// add a reference to our security data source
#Autowired
private DataSource securityDataSource;
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
/*
//inMemoryAuthentication deprecated in latest Spring
auth.inMemoryAuthentication().withUser("john").password("111").roles(
"EMPLOYEE");
auth.inMemoryAuthentication().withUser("mary").password("111").roles(
"EMPLOYEE", "MANAGER");
auth.inMemoryAuthentication().withUser("susan").password("111").roles(
"EMPLOYEE", "ADMIN");
*/
// use jdbc aunthetication
// tell Spring Security to use JDBC authentication with our data source
auth.jdbcAuthentication().dataSource(securityDataSource);
}
/**
* Configure security of web paths in application, login, logout etc
*/
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// .anyRequest().authenticated() // any request to the app must be authenticated
// (i.e. logging in)
.antMatchers("/").hasRole("EMPLOYEE").antMatchers("/leaders/**").hasRole("MANAGER")
// show our custom form at the request mapping "/showMyLoginPage"
.antMatchers("/systems/**").hasRole("ADMIN").and().formLogin().loginPage("/showLoginPage")
.loginProcessingUrl("/authenticateTheUser") // Login form should POST data to this URL for processing
// (check username & password)
.usernameParameter("username") // don't add this in spring 5
.passwordParameter("password") // don't add this in spring 5
.permitAll() // Allow everyone to see login page. No need to be logged in.
.and().logout().permitAll().and().exceptionHandling().accessDeniedPage("/access-denied");
}
}
Here is MvcDispatchServletInitializer
public class AppSpringMvsDispatcherServlerInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {AppConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
}
Here is SecurityWebApplicationInitializer
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
}
Here is pom.xml
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
<groupId>com.nike.mycoolwebapp</groupId>
<artifactId>mycoolwebapp</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>mycoolwebapp</name>
<properties>
<springframework.version>4.1.6.RELEASE</springframework.version>
<springsecurity.version>4.0.1.RELEASE</springsecurity.version>
<c3po.version>0.9.5.2</c3po.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- Spring MVC support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- Spring Security -->
<!-- spring-security-web and spring-security-config -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${springsecurity.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${springsecurity.version}</version>
</dependency>
<!-- Add Spring Security Taglibs support -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${springsecurity.version}</version>
</dependency>
<!-- Add MySQL support -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<!-- Add c3p0 support -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>${c3po.version}</version>
</dependency>
<!-- Servlet, JSP and JSTL support -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- to compensate for java 9+ not including jaxb -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- TO DO: Add support for Maven WAR Plugin -->
<build>
<finalName>mycoolwebapp</finalName>
<pluginManagement>
<plugins>
<plugin>
<!-- Add Maven coordinates (GAV) for: maven-war-plugin -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
Here is AppController
#Controller
public class AppController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public String showHome() {
return "home";
}
// add a request mapping for /leaders
#RequestMapping(value = "/leaders", method = RequestMethod.GET)
public String showLeader() {
return "leaders";
}
// add a request mapping for /systems
#RequestMapping(value = "/systems", method = RequestMethod.GET)
public String showAdmin() {
return "systems";
}
}
Here is the Login Controller.
#Controller
public class LoginController {
#RequestMapping(value = "/showLoginPage", method = RequestMethod.GET)
public String showLoginPage() {
return "fancy-login";
}
// add a request mapping for /access-denied
#RequestMapping(value = "/access-denied", method = RequestMethod.GET)
public String showAccessDenied() {
return "access-denied";
}
}
Here are MySQL tables
Remove {noop} from the database. {noop} or {bcrypt} is in Spring 5.
Sorry for the question being too generic, but someone has some tutorial or guide on how to perform producer and consumer testing with kafka embedded. I've tried several, but there are several versions of dependencies and none actually works =/
I'm using spring cloud stream kafka.
We generally recommend using the Test Binder in tests but if you want to use an embedded kafka server, it can be done...
Add this to your POM...
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka-test</artifactId>
<scope>test</scope>
</dependency>
Test app...
#SpringBootApplication
#EnableBinding(Processor.class)
public class So43330544Application {
public static void main(String[] args) {
SpringApplication.run(So43330544Application.class, args);
}
#StreamListener(Processor.INPUT)
#SendTo(Processor.OUTPUT)
public byte[] handle(byte[] in){
return new String(in).toUpperCase().getBytes();
}
}
application.properties...
spring.cloud.stream.bindings.output.destination=so0544out
spring.cloud.stream.bindings.input.destination=so0544in
spring.cloud.stream.bindings.output.producer.headerMode=raw
spring.cloud.stream.bindings.input.consumer.headerMode=raw
spring.cloud.stream.bindings.input.group=so0544
Test case...
#RunWith(SpringRunner.class)
#SpringBootTest
public class So43330544ApplicationTests {
#ClassRule
public static KafkaEmbedded embeddedKafka = new KafkaEmbedded(1);
#Autowired
private KafkaTemplate<byte[], byte[]> template;
#Autowired
private KafkaProperties properties;
#BeforeClass
public static void setup() {
System.setProperty("spring.kafka.bootstrap-servers", embeddedKafka.getBrokersAsString());
}
#Test
public void testSendReceive() {
template.send("so0544in", "foo".getBytes());
Map<String, Object> configs = properties.buildConsumerProperties();
configs.put(ConsumerConfig.GROUP_ID_CONFIG, "test0544");
configs.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
ConsumerFactory<byte[], byte[]> cf = new DefaultKafkaConsumerFactory<>(configs);
Consumer<byte[], byte[]> consumer = cf.createConsumer();
consumer.subscribe(Collections.singleton("so0544out"));
ConsumerRecords<byte[], byte[]> records = consumer.poll(10_000);
consumer.commitSync();
assertThat(records.count()).isEqualTo(1);
assertThat(new String(records.iterator().next().value())).isEqualTo("FOO");
}
}
Hello i am a fresher i just took i application from online was trying to run it parameters i am using is
Maven
SpringMVC
Mysql
Java
Eclipse
i am able to create a table in the database with this code and delet also but when i am trying to dete it withoutr using save option it's giving me error
****org.hibernate.event.def.DefaultDeleteEventListener deleteTransientEntity
INFO: handling transient entity in delete processing****
when i checked online it show to get the object of the row in the app.java page then delete that object to delete the row i don't know how to get that object and how to pass the row of the database in that object(how to get that field mbedded into the object and how to get that object)plz help all i want is to delete a row from the database base on some column name specific value
App.java class
package com.mkyong.common;
import org.hibernate.Session;
import com.mkyong.persistence.HibernateUtil;
public class App
{
public static void main( String[] args )
{
System.out.println("Maven + Hibernate + MySQL");
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Stock stock = new Stock();
stock.setStockCode("4715");
stock.setStockName("GENM");
stock.getStockCode();
stock.getStockName();
//session.save(stock);
session.delete(stock);
session.getTransaction().commit();
}
}
AppTest.java
package com.mkyong.common;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
/**
* Create the test case
*
* #param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}
/**
* #return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite( AppTest.class );
}
/**
* Rigourous Test :-)
*/
public void testApp()
{
assertTrue( true );
}
}
Stock.java
package com.mkyong.common;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
#Entity
#Table(name = "stock", catalog = "gagan", uniqueConstraints = {
#UniqueConstraint(columnNames = "STOCK_NAME"),
#UniqueConstraint(columnNames = "STOCK_CODE") })
public class Stock implements java.io.Serializable {
private Integer stockId;
private String stockCode;
private String stockName;
public Stock() {
}
public Stock(String stockCode, String stockName) {
this.stockCode = stockCode;
this.stockName = stockName;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "STOCK_ID", unique = true, nullable = false)
public Integer getStockId() {
return this.stockId;
}
public void setStockId(Integer stockId) {
this.stockId = stockId;
}
#Column(name = "STOCK_CODE", unique = true, nullable = false, length = 10)
public String getStockCode() {
return this.stockCode;
}
public void setStockCode(String stockCode) {
this.stockCode = stockCode;
}
#Column(name = "STOCK_NAME", unique = true, nullable = false, length = 20)
public String getStockName() {
return this.stockName;
}
public void setStockName(String stockName) {
this.stockName = stockName;
}
}
HibernateUtil.java
package com.mkyong.persistence;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new AnnotationConfiguration().configure().buildSessionFactory();
}
catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
// Close caches and connection pools
getSessionFactory().close();
}
}
hibernatecfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- Database connection settings -->
<!-- UAT Database connection settings -->
<property name="connection.url">jdbc:mysql://localhost:3306/gagan</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- Think Before made any change in below flag may that clean you complete database -->
<mapping class="com.mkyong.common.Stock"></mapping>
</session-factory>
</hibernate-configuration>
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mkyong.common</groupId>
<artifactId>HibernateExample</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>HibernateExample</name>
<url>http://maven.apache.org</url>
<repositories>
<repository>
<id>JBoss repository</id>
<url>http://repository.jboss.com/maven2/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- MySQL database driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
<!-- Hibernate core -->
<dependency>
<groupId>hibernate</groupId>
<artifactId>hibernate3</artifactId>
<version>3.2.3.GA</version>
</dependency>
<!-- Hibernate annotation -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.5.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>4.3.5.Final</version>
</dependency>
<!-- Hibernate library dependecy start -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>
<!-- Hibernate library dependecy end -->
</dependencies>
</project>
[1]: http://i.stack.imgur.com/tkv2h.png
You can not delete transient object. You need to first synchronize the object with the database. For example you got id of your stock component. Here is a sample piece of code to delete the object based on stockId. Even when you create an object using hibernate it return ID. Use this ID to delete the row from database.
Session session = HibernateUtil.getSessionFactory().openSession();
try {
session.beginTransaction();
Serializable id = stockId;
Object persistentInstance = session.load(Stock.class, id);
if (persistentInstance != null) {
session.delete(persistentInstance);
session.getTransaction().commit();
System.out.println ("Deleted Sucessfully");
}
else {
System.out.println ("Did not find the Stock Object in persistance");
}
}
catch (HibernateException e) {
e.printStackTrace();
}
finally {
if(session!=null){
session.close();
}
}
Stock object is in Transient state ,to delete it, it should be persist in database also note that when you try to delete any object its primary key should be set with it otherwise it will not reflect any changes into the database as STOCK_ID is primary key here .
I'm using Jackson JSON provider in order to serialize/deserialize JAXRS requests.
In order to set it up I've a jboss-deployment-structure.xml file under WEB-INF folder:
<jboss-deployment-structure>
<deployment>
<exclusions>
<module name="org.jboss.resteasy.resteasy-jackson-provider"/>
<module name="org.jboss.resteasy.resteasy-jettison-provider"/>
</exclusions>
<dependencies>
<module name="org.jboss.resteasy.resteasy-jackson2-provider" services="import"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
So, I've built a test in order to get it:
#RunWith(Arquillian.class)
public class FollowUpActivityDTOSerializationTest
{
#Inject private ObjectMapper mapper;
#Deployment
public static WebArchive createDeployment()
{
System.getProperties().remove("javax.xml.parsers.SAXParserFactory");
EmbeddedGradleImporter importer = ShrinkWrap.create(EmbeddedGradleImporter.class);
WebArchive war = importer.forThisProjectDirectory().importBuildOutput().as(WebArchive.class);
war.addClass(ArquillianAlternative.class);
war.addClass(MockFactory.class);
war.addAsWebInfResource(
new StringAsset("<alternatives><stereotype>com.living.mock.ArquillianAlternative</stereotype></alternatives>"),
"beans.xml"
);
JavaArchive[] libs = Maven.resolver().resolve("org.mockito:mockito-core:2.0.31-beta").withTransitivity().as(JavaArchive.class);
war.addAsLibraries(libs);
return war;
}
#Test
public void emptyJSON()
{
String emptyJSON = "{\"id\": \"id\"}";
try {
FollowUpActivityDTO dto = this.mapper.readValue(emptyJSON, FollowUpActivityDTO.class);
assertNotNull(dto);
assertEquals(dto.getId(), "id");
} catch (IOException e) {
fail(e.getMessage());
}
}
}
The problem is Weld tells me that:
Unsatisfied dependencies for type ObjectMapper with qualifiers #Default
The question, how can I get the jackson provider?
The most important thing here is to get in testing time, the same ObjectMapper that JAX-RS implementation would use.
It's important because I configure some settings related to this object in my provider:
#Provider
#Produces(MediaType.APPLICATION_JSON)
public class JacksonConfig implements ContextResolver<ObjectMapper> {
#Override
public ObjectMapper getContext(final Class<?> type) {
final ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.setSerializationInclusion(Include.NON_EMPTY);
return mapper;
}
}
So, it's important to use this provider.
So, in order to inject this object I've written this injection code:
#Inject private ContextResolver<ObjectMapper> mapperResolver;
By default, there is no producer for ObjectMapper unless you explicitly provided one. If you replace your injection point with an instantiation of the ObjectMapper, e.g. private ObjectMapper objectMapper = new ObjectMapper() you'll avoid the injection problem.