I am currently working on one of the requirements where I wanted to POST some data in my database.
In my database named template_data I have three columns called id,json_data & timestamp. The json_data column will hold the json where the json values will be coming from the user such as:
"suggestions": [
{
"reply": {
"text": "**Tobe given by user**",
"postbackData": "**Tobe given by user**"
}
}
I have to construct this JSON through my code what I am doing here in the below code
package com.airkommtemplate.springboot.RCMTemplate.controller;
import com.airkommtemplate.springboot.RCMTemplate.entity.TemplateData;
import com.airkommtemplate.springboot.RCMTemplate.service.TemplateServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.time.LocalDateTime;
import java.util.List;
@Controller
@RequestMapping("/templates")
public class TemplateController {
private TemplateServiceImpl templateService;
@Autowired
public TemplateController(TemplateServiceImpl theTemplateService){
templateService = theTemplateService;
}
@GetMapping("/form")
public String showForm(Model model) {
model.addAttribute("template", new TemplateData());
return "templates/template-form"; // Thymeleaf template file name (e.g., template-form.html)
}
@GetMapping("/list")
public String listTemplateData(Model theModel) {
List<TemplateData> theTemplateList =templateService.findAll();
// add to the spring model
theModel.addAttribute("templates", theTemplateList);
return "templates/list-templates";
}
@PostMapping("/save")
public String saveData(@ModelAttribute("template") TemplateData template) {
// Construct the complete JSON structure using user input
String jsonData = "{\"suggestions\": [{" +
"\"reply\": {" +
"\"text\": \"" + template.getText() + "\"," +
"\"postbackData\": \"" + template.getPostbackData() + "\"" +
"}}]}";
// Set timestamp
template.setTimestamp(LocalDateTime.now());
// Save the complete JSON data to the database
template.setJsonData(jsonData);
templateService.saveData(template);
return "redirect:/templates/list";
//return "redirect:/success"; // Redirect to a success page
}
}
The service
package com.airkommtemplate.springboot.RCMTemplate.service;
import com.airkommtemplate.springboot.RCMTemplate.dao.TemplateDataRepository;
import com.airkommtemplate.springboot.RCMTemplate.entity.TemplateData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class TemplateServiceImpl implements TemplateService{
private final TemplateDataRepository templateDataRepository;
@Autowired
public TemplateServiceImpl(TemplateDataRepository templateDataRepository) {
this.templateDataRepository = templateDataRepository;
}
@Override
public List<TemplateData> findAll() {
return templateDataRepository.findAll();
}
@Override
public void saveData(TemplateData templateData) {
//TemplateData templateData = new TemplateData();
templateData.setTimestamp(LocalDateTime.now());
templateDataRepository.save(templateData);
}
}
The Repository (DAO)
package com.airkommtemplate.springboot.RCMTemplate.dao;
import com.airkommtemplate.springboot.RCMTemplate.entity.TemplateData;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface TemplateDataRepository extends JpaRepository<TemplateData, Integer> {
}
My entity class holds below parameters
@Entity
@Table(name="template_data")
public class TemplateData {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private int id;
@Column(name="json_data")
private String jsonData;
@Column(name="timestamp")
private LocalDateTime timestamp;
private String text;
private String postbackData;
When I am trying to save this data using /templates/save api it is throwing the error below:
There was an unexpected error (type=Internal Server Error, status=500).
could not execute statement; SQL [n/a]
org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n/a]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:256)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:232)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:550)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:243)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:164)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:244)
at jdk.proxy4/jdk.proxy4.$Proxy111.save(Unknown Source)
at com.airkommtemplate.springboot.RCMTemplate.service.TemplateServiceImpl.saveData(TemplateServiceImpl.java:29)
at com.airkommtemplate.springboot.RCMTemplate.controller.TemplateController.saveData(TemplateController.java:59).......
Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'postback_data' in 'field list'
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:121)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122......
I have tried changing the parameters of template type which I am passing in my controllers to service call, but nothing is working out.
Java's transient keyword is used to denote that a field is not to be serialized, whereas JPA's @Transient annotation is used to indicate that a field is not to be persisted in the database, i.e. their semantics are different.
So make the following changes:
@Transient
private String text;
@Transient
private String postbackData;