What are the depencencies to be added to get the XML output in spring-mvc? - spring

What are the maven dependencies need to be added to get the XML output without configuring content negotiation view resolver and managers. By using the default Message Converters based on jars on classpath (output based on accept headers). I am able to get the JSON output by having jackson-databind dependency on the classpath. For XML I am using
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.7</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${org.springframework.version}</version>
</dependency>
dependencies - I am unable to get the XML output. DO I need configure any Marshallers like Jaxb2Marsahllar as a bean in the configuration file. Can Any post the maven dependencies for JAXB2.
My Entity class:
package com.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.hibernate.validator.constraints.NotEmpty;
#Entity
#Table(name = "Employee")
#XmlRootElement
public class Employee {
public Employee() {
}
public Employee(Integer empno, String name, String dept, Double salary) {
this.empno = empno;
this.name = name;
this.dept = dept;
this.salary = salary;
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer empno;
#Size(min = 1, max = 30)
#NotEmpty
private String name;
#NotEmpty
#Size(min = 1, max = 30)
private String dept;
/*
* #NotEmpty - cannot be set to double - supports String Collection Map
* arrays
*/
private Double salary;
#XmlAttribute
public Integer getEmpno() {
return empno;
}
public void setEmpno(Integer empno) {
this.empno = empno;
}
#XmlElement
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlElement
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
#XmlElement
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
#Override
public String toString() {
return "Employee [empno=" + empno + ", name=" + name + ", dept=" + dept
+ ", salary=" + salary + "]";
}
}
My Controller Class:
#Controller
public class EmployeeController {
#Autowired
EmployeeRepository employeeRepository;
#RequestMapping(value = "/employees", method=RequestMethod.GET,
produces= {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public #ResponseBody List<Employee> findAllXml(){
return employeeRepository.findAll();
}
}
Please Can any one say Whether the dependencies are enough ? What needs to be added..

put #XMLElement on set methods.
public Integer getEmpno() {
return empno;
}
#XmlAttribute
public void setEmpno(Integer empno) {
this.empno = empno;
}
public String getName() {
return name;
}
#XmlElement
public void setName(String name) {
this.name = name;
}
or you can use Spring Marshalling View of spring-oxm.jar
<bean id="xmlViewer"
class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.model.Employee</value>
</list>
</property>
</bean>
</constructor-arg>
</bean>
Update:1
Also findAll is returning list that list needs to be accomodated in a parent tag like
<Employees>
<Employee />
<Employee />
</Employees>
so you need to define a class that has an #XMLElement entity as List<Employees> create object of it put the data in it and return that object.

I found the answer to 406 exception
Problem was needed an extra configuration for Message Converters for XML output.
For XML Output, we need to Added a Message Converter to the list of Message converters of RequestMappingHandlerAdapter
But for JSON we dont need to do this explictly, based on the jackson-databind dependencies on the classpath, we can able get the JSON output. But for xml , we need to add a message converter (MarshallingHttpMessageConverter) .
Example: Using Java Based Config: configuring RequestMappingHandlerAdapter as a bean and adding required Message Converters...
#Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter();
List<HttpMessageConverter<?>> converters = new ArrayList();
converters.add(new MarshallingHttpMessageConverter(
new XStreamMarshaller()));
converters.add(new MappingJackson2HttpMessageConverter());
adapter.setMessageConverters(converters);
return adapter;
}
I am using XStream Marshaller, so need to add its dependencies as well
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.8</version>
</dependency>
Example Tests:
#Test
public void testXml() throws Exception {
this.mvc.perform(get("/employees/xml").accept(APPLICATION_XML))
.andDo(print())
.andExpect(content().contentType("application/xml"));
}
#Test
public void testJson() throws Exception {
this.mvc.perform(get("/employees/json").accept(APPLICATION_JSON))
.andDo(print())
.andExpect(content().contentType("application/json"));
}
Please post if you know any other way of doing this.
useful link: Spring XML 406 error

Related

Not able to save data in cosmos db through spring boot micro service

i'm trying to save entity in cosmos db through spring boot micro service. I'm not getting any error, only 1 warning '[osEventLoop-6-1] c.a.d.c.i.d.rntbd.RntbdRequestManager : ChannelHandlerContext(RntbdRequestManager#0, [id: 0x999bfbac, L:0.0.0.0/0.0.0.0:56979 ! R:cdb-ms-prod-*****-****.documents.azure.com/********]) channelUnregistered exceptionally'
but data is not getting saved in cosmos db. i'm using reactivecosmosrepository.
here is my pom.xml
<properties>
<java.version>1.8</java.version>
<azure.version>2.2.0</azure.version>
</properties>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-cosmosdb-spring-boot-starter</artifactId>
<version>${azure.version}</version>
</dependency>
my entity
import com.microsoft.azure.spring.data.cosmosdb.core.mapping.Document;
#Document(collection = "dashboardsnapshot")
public class DashboardSnapshot {
private String id;
private String clientId;
private String snapshotJSON;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getSnapshotJSON() {
return snapshotJSON;
}
public void setSnapshotJSON(String snapshotJSON) {
this.snapshotJSON = snapshotJSON;
}
#Override
public String toString() {
return "DashboardSnapshot [id=" + id + ", clientId=" + clientId + ", snapshotJSON=" + snapshotJSON + "]";
}
}
my repository
import org.springframework.stereotype.Repository;
import com.ka.concept.dashboardconfig.entity.DashboardSnapshot;
import com.microsoft.azure.spring.data.cosmosdb.repository.ReactiveCosmosRepository;
import reactor.core.publisher.Flux;
#Repository
public interface SnapshotDao extends ReactiveCosmosRepository<DashboardSnapshot, String>{
Flux<DashboardSnapshot> findbyClientId(String ClientId);
}
my service
#Service
public class SnapshotServiceImpl implements SnapshotService{
#Autowired
public SnapshotDao snapshotdao;
#Override
public boolean saveSnapshotConfig(DashboardSnapshot snapshotJSON) {
// TODO Auto-generated method stub
snapshotdao.save(snapshotJSON);
return true;
}
}
#AksYou should call subscribe(). The publisher does not do anything till some one subscribes.
snapshotdao.save(snapshotJSON).subscribe();

Transaction support in spring-boot running Tomcat, with AspectJ load-time weaving (LTW)

I am having a hard time configuring transactional support in spring-boot 2.0.3 with AspectJ LTW (load-time weaving). My spring-boot is running embedded Tomcat servlet container. In my persistence layer, I am not using JPA, but Spring JDBC Template instead.
I opted for AspectJ mode for transaction management because we are leveraging a rather big project with nested transactions and sometimes it is hard to keep track of all the applications of #Transactional annotation. So that when this annotation is being used I want to have a predictable result - atomic DB operation. I do not want to think about whether we have a self-invocation or method that is marked to be transactional is public.
I have read a bunch of documentation regarding transaction support in spring and how to configure LTW AspectJ weaving.
Unfortunately, I cannot make it work. I have created a test (spring-boot test class) that is meant to mimic different failures in a code that should be transactional (see it below). Also, I cannot see the weaving actually happening. I am clearly missing something, cannot figure out what.
My test class:
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = TestConfig.class)
#ActiveProfiles("TEST")
public class TransactionalIT {
#SpyBean
private JdbcTemplate jdbcTemplate;
// we need this guy in order to perform a cleanup in static #AfterClass method
private static JdbcTemplate jdbcTemplateInStaticContext;
#Autowired
private PlatformTransactionManager txManager;
#Spy
private NestedTransactionsJdbcDao dao;
#Before
public void setUp() {
if (jdbcTemplateInStaticContext == null) {
// Making sure we're working with the proper tx manager
assertThat(txManager).isNotNull();
assertThat(txManager.getClass()).isEqualTo(DataSourceTransactionManager.class);
jdbcTemplateInStaticContext = jdbcTemplate;
jdbcTemplateInStaticContext.execute("CREATE TABLE entity_a (id varchar(12) PRIMARY KEY, name varchar(24), description varchar(255));");
jdbcTemplateInStaticContext.execute("CREATE TABLE entity_b (id varchar(12) PRIMARY KEY, name varchar(24), description varchar(255));");
jdbcTemplateInStaticContext.execute("CREATE TABLE entity_a_to_b_assn (entity_a_id varchar(12) NOT NULL, entity_b_id varchar(12) NOT NULL, " +
"CONSTRAINT fk_entity_a FOREIGN KEY (entity_a_id) REFERENCES entity_a(id), " +
"CONSTRAINT fk_entity_b FOREIGN KEY (entity_b_id) REFERENCES entity_b(id), " +
"UNIQUE (entity_a_id, entity_b_id));");
}
}
#AfterClass
public static void cleanup() {
if (jdbcTemplateInStaticContext != null) {
jdbcTemplateInStaticContext.execute("DROP TABLE entity_a_to_b_assn;");
jdbcTemplateInStaticContext.execute("DROP TABLE entity_a;");
jdbcTemplateInStaticContext.execute("DROP TABLE entity_b;");
}
}
#Test
public void createObjectGraph_FailsDuring_AnAttemptToCreate3rdEntityA() {
doThrow(new RuntimeException("blah!")).when(jdbcTemplate).update(eq("INSERT INTO entity_a (id, name, description) VALUES(?, ?, ?);"),
eq("a3"), eq("entity a3"), eq("descr_a_3"));
try {
dao.createObjectGraph(getObjectGraph());
fail("Should never reach this point");
} catch (RuntimeException e) {
assertThat(e.getMessage()).isEqualTo("blah!");
assertDbCounts(0L, 0L, 0L);
}
}
private void assertDbCounts(long expectedACount, long expectedBCount, long expectedAToBCount) {
Long actualACount = jdbcTemplate.queryForObject("SELECT count(*) count_a FROM entity_a", new LongRowMapper());
assertThat(actualACount).isEqualTo(expectedACount);
Long actualBCount = jdbcTemplate.queryForObject("SELECT count(*) count_b FROM entity_b", new LongRowMapper());
assertThat(actualBCount).isEqualTo(expectedBCount);
Long actualAToBCount = jdbcTemplate.queryForObject("SELECT count(*) count_a_to_b FROM entity_b", new LongRowMapper());
assertThat(actualAToBCount).isEqualTo(expectedAToBCount);
}
private final class LongRowMapper implements RowMapper<Long> {
#Override
public Long mapRow(ResultSet resultSet, int i) throws SQLException {
return resultSet.getLong(1);
}
}
private ObjectGraph getObjectGraph() {
EntityA a1 = new EntityA("a1", "entity a1", "descr_a_1");
EntityA a2 = new EntityA("a2", "entity a2", "descr_a_2");
EntityA a3 = new EntityA("a3", "entity a3", "descr_a_3");
EntityB b1 = new EntityB("b1", "entity b1", "descr_b_1");
EntityB b2 = new EntityB("b2", "entity b2", "descr_b_2");
EntityB b3 = new EntityB("b3", "entity b3", "descr_b_3");
AtoBAssn a1b1 = new AtoBAssn("a1", "b1");
AtoBAssn a1b3 = new AtoBAssn("a1", "b3");
AtoBAssn a2b2 = new AtoBAssn("a2", "b2");
AtoBAssn a2b3 = new AtoBAssn("a2", "b3");
AtoBAssn a3b1 = new AtoBAssn("a3", "b1");
return new ObjectGraph(
Lists.newArrayList(a1, a2, a3),
Lists.newArrayList(b1, b2, b3),
Lists.newArrayList(a1b1, a1b3, a2b2, a2b3, a3b1));
}
#Data
#AllArgsConstructor
private class EntityA {
private String id;
private String name;
private String description;
}
#Data
#AllArgsConstructor
private class EntityB {
private String id;
private String name;
private String description;
}
#Data
#AllArgsConstructor
private class AtoBAssn {
private String idA;
private String idB;
}
#Data
#AllArgsConstructor
private class ObjectGraph {
private List<EntityA> aList;
private List<EntityB> bList;
List<AtoBAssn> aToBAssnList;
}
#Repository
public class NestedTransactionsJdbcDao {
#Transactional
public void createObjectGraph(ObjectGraph og) {
createEntitiesA(og.getAList());
createEntitiesB(og.getBList());
createAtoBAssn(og.getAToBAssnList());
doSomethingElse();
}
#Transactional
public void createEntitiesA(List<EntityA> aList) {
aList.forEach(a ->
jdbcTemplate.update("INSERT INTO entity_a (id, name, description) VALUES(?, ?, ?);",
a.getId(), a.getName(), a.getDescription()));
}
#Transactional
public void createEntitiesB(List<EntityB> bList) {
bList.forEach(b ->
jdbcTemplate.update("INSERT INTO entity_b (id, name, description) VALUES(?, ?, ?);",
b.getId(), b.getName(), b.getDescription()));
}
#Transactional
/**
* Intentionally access is set to package-private
*/
void createAtoBAssn(List<AtoBAssn> aToBAssnList) {
aToBAssnList.forEach(aToB ->
jdbcTemplate.update("INSERT INTO entity_a_to_b_assn (entity_a_id, entity_b_id) VALUES(?, ?);",
aToB.getIdA(), aToB.getIdB()));
}
void doSomethingElse() {
// Intentionally left blank
}
}
}
Here is my configuration class:
import org.apache.catalina.loader.WebappClassLoader;
import org.springframework.context.annotation.AdviceMode;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableLoadTimeWeaving;
import org.springframework.context.annotation.Primary;
import org.springframework.instrument.classloading.LoadTimeWeaver;
import org.springframework.instrument.classloading.tomcat.TomcatLoadTimeWeaver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.aspectj.AnnotationTransactionAspect;
#Configuration
#EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
#EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
public class EventCoreConfig {
#Bean
public LoadTimeWeaver loadTimeWeaver() {
// https://tomcat.apache.org/tomcat-8.0-doc/api/org/apache/tomcat/InstrumentableClassLoader.html
return new TomcatLoadTimeWeaver(new WebappClassLoader());
}
#Bean
#Primary
public PlatformTransactionManager txManager(DataSource dataSource) {
DataSourceTransactionManager txManager = new DataSourceTransactionManager(dataSource);
AnnotationTransactionAspect aspect = new AnnotationTransactionAspect();
aspect.setTransactionManager(txManager);
return txManager;
}
}
Here is the portion of my pom.xml that is adding dependencies of interest:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>ch.vorburger.mariaDB4j</groupId>
<artifactId>mariaDB4j</artifactId>
<version>2.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>2.4.0</version>
<scope>test</scope>
</dependency>
Any help will be greatly appreciated. I know this is a little advanced topic, but I do not think it should be that complicated. I think Spring's documentation lacks examples of how to properly perform this kind of configuration. Also, I haven't found any success stories over there with a similar setup.

Spring Controller - Testing to receive nested dto with multipartfile inside with postman

I'm working on a service which accepts a DTO in a POST method and creates an entity based on that DTO. Nested inside is a multipart file, which is going to be an image used by the entity that will be created.
Using postman to test my backend, I keep receiving an seemingly empty DTO. The three logs inside the controller return null, 0 and null respectively.
This is how I setup my data, which I am quite sure is the problem:
I converted my image into a base64 string, which as far as I know is the only way I can post a nested image.
Code
Controller
#PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<InventoryComponentDto> create(#ModelAttributee InventoryComponentDto request) {
System.out.println(request.getDescription());
System.out.println(request.getMinimal_supply());
System.out.println(request.getComponent());
InventoryComponentDto result = inventoryComponentService.create(request);
if (result == null) {
return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
}
return ResponseEntity.ok(result);
}
InventoryComponentDto
public class InventoryComponentDto {
private ComponentDto component;
private String description;
private Date createdAt;
private Date updatedAt;
private int minimal_supply;
private int supply;
}
ComponentDto
public class ComponentDto {
private Long id;
private int number;
private String name;
private FileDto image;
}
FileDto
public class FileDto {
private String name;
private String type;
private String url;
private MultipartFile data;
}
What would be the way for me to adequately create my dto in postman, including an image?
Update
"status": 400,
"error": "Bad Request",
"message": "JSON parse error: (was java.lang.NullPointerException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.package.MCI.dto.InventoryComponentDto[\"component\"]->com.package.MCI.dto.ComponentDto[\"image\"])",
"trace": "org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: (was java.lang.NullPointerException); nested...
You need to create a custom jackson deserializer.
//CustomDeserializer
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.springframework.util.Base64Utils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
public class CustomDeserializer extends StdDeserializer<FileDTO> {
public CustomDeserializer() {
super(FileDTO.class);
}
protected CustomDeserializer(Class<?> vc) {
super(vc);
}
#Override
public FileDTO deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext)
throws IOException, JsonProcessingException {
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
String name = node.get("name").asText();
String url = node.get("url").asText();
String type = "." + node.get("type").asText();
String fileBase64 = node.get("data").asText();
byte[] fileBytes = Base64Utils.decodeFromString(fileBase64);
FileItem fileItem = new DiskFileItem(name, "image/jpg", false, name + type,
fileBytes.length, null);
fileItem.getOutputStream().write(fileBytes);
fileItem.getOutputStream().flush();
MultipartFile file = new CommonsMultipartFile(fileItem);
fileItem.getOutputStream().close();
FileDTO fileDTO = new FileDTO();
fileDTO.setName(name);
fileDTO.setUrl(url);
fileDTO.setType(type);
fileDTO.setData(file);
return fileDTO;
}
}
And use it like:
//FileDTO
#JsonDeserialize(using = CustomDeserializer.class)
public class FileDTO {
You need these two dependencies:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>

Spring JDBC update without commit

I have a simple table "employee" defined as:
create table employee (id int, name varchar2(40));
I want to write an application to insert values in it and commit only after all values are inserted. Here is my code:
Employee.java:
package com.empl;
public class Employee {
private int id;
private String name;
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
EmployeeDAO.java:
package com.empl;
import javax.sql.DataSource;
public interface EmployeeDAO {
public void setDataSource(DataSource dataSource);
public void create(int id, String name);
}
EmployeeJDBCTemplate.java:
package com.empl;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
public class EmployeeJDBCTemplate {
private DataSource dataSource;
private JdbcTemplate jdbcTemplateObject;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
this.jdbcTemplateObject = new JdbcTemplate(dataSource);
}
public DataSource getDataSource() {
return dataSource;
}
public void create(int id, String name) {
String SQL = "insert into employee (id, name) values (?, ?)";
jdbcTemplateObject.update(SQL, id, name);
}
}
MainApp.java:
package com.empl;
import java.sql.SQLException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String args[]) throws SQLException {
ApplicationContext context = new
ClassPathXmlApplicationContext("Beans.xml");
EmployeeJDBCTemplate employeeJDBCTemplate =
(EmployeeJDBCTemplate) context.getBean("employeeJDBCTemplate");
employeeJDBCTemplate.getDataSource().getConnection().
setAutoCommit(false);
employeeJDBCTemplate.create(1, "E1");
employeeJDBCTemplate.create(2, "E2");
}
}
Beans.xml:
<beans xmlns = "http://www.springframework.org/schema/beans"
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-3.0.xsd ">
<bean id = "dataSource" class =
"org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name = "driverClassName" value =
"oracle.jdbc.driver.OracleDriver"></property>
<property name = "url" value =
"jdbc:oracle:thin:#localhost:1521/xe"></property>
<property name = "username" value = "sys as sysdba"></property>
<property name = "password" value = "pass"></property>
</bean>
<bean id = "employeeJDBCTemplate" class =
"com.empl.EmployeeJDBCTemplate">
<property name = "dataSource" ref = "dataSource"></property>
</bean>
</beans>
I executed the code but when I enter SQLPlus and type the rollback; command, the records are still in the table.
I saw related questions but nothing seems to work.

Jackson doesn't serialize nested classes in Spring

I have an implementation of a REST front-end UI and a Spring JPA based backend.
In it, I have a class like this:
public class TaskInfo {
// 4 fields
private Parent parentList;
// 3 fields
// Getters and Setters
}
class Parent {
// Parent class code
}
When I try to take a Response, I find that in place of Parent, I get a null value. Why is this Parent object not getting serialized? Is there a workaround to this? Or should I just include the fields of Parent in this class directly?
Edit: I'm using Jackson for serialization.
For me the below works fine. I think this is equivalent to the code present in your question
package jackson;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class TaskInfo {
public TaskInfo(String id, Parent parentList) {
super();
this.id = id;
this.parentList = parentList;
}
private String id;
private Parent parentList;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Parent getParentList() {
return parentList;
}
public void setParentList(Parent parentList) {
this.parentList = parentList;
}
public static void main(String args[]) throws IOException {
Parent parent = new Parent("123");
TaskInfo taskInfo = new TaskInfo("taskID", parent);
String json = new ObjectMapper().writeValueAsString(taskInfo);
System.out.println(json);
}
}
class Parent {
public Parent(String parentId) {
this.parentId = parentId;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
private String parentId;
// Parent class code
}
It prints the following output
{"id":"taskID","parentList":{"parentId":"123"}}
I used jackson
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.1</version>
</dependency>
It doesn't serialize because your properties are not public. Make the properties public and it works.

Resources