Spring Boot Repository.save() methods do not work - No commit - java

I scan two QR code and try to get them from My QR Code Android Mobile App and save it with repository.save() in my Local db.
My app send List to Backend but don't insert to db. When I run localhost/8090, i don't get back anything.
In Browser show only this:
-Find Devices
-Device Code
-Device ID
Developer.java
#Entity
public class Developer {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id = 0;
private String deviceCode;
private String deviceId;
public Developer() {
super();
}
public Developer(String deviceCode, String deviceID)
{
super();
this.deviceCode = deviceCode;
this.deviceId = deviceId;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String deviceCode() {
return deviceCode;
}
public void set DeviceCode(String deviceCode) {
this.deviceCode;
}
public String deviceId() {
return deviceId;
}
public void set DeviceId(String deviceId) {
this.deviceId;
}
}
DeveloperRepository.java
import org.springframework.data.repository.CrudRepository;
public interface DeveloperRepository extends CrudRepository<Developer, Long> {
}
DeveloperController.java
#Controller
public class DevelopersController {
#Autowired
DeveloperRepository repository;
#RequestMapping(value = "/", method = RequestMethod.POST)
#ResponseBody
private String addDevices(Developer deviceCodeAndId) {
System.out.println("xyz!");
if (!repository.exists(deviceCodeAndId.getId())) {
repository.save(deviceCodeAndId);
return "successfully added " + deviceCodeAndId.getId();
}
return deviceCodeAndId.getId();
}
#RequestMapping(value = "/showall",method = RequestMethod.GET)
public String index(Model model) {
model.addAttribute("index",repository.findAll());
return "index";
}
}
deviceCodeAndID is Class from Android App which scanned with app!
index.html

Have you enabled transaction management. Even you use Spring boot data repository. You need to enable transaction management, else by default everything will be read mode. And for read mode there is no need to transaction. But when you do any operation that will change data in DB, you need to perform transaction management.
Use #EnableTransactionManagement on in application class, and #Transactional in DAO or service class

#SpringBootApplication
public class Application {
#Autowired
DeveloperRepository developerRepository;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
Here is my Application Class

Related

#SpringBootTest runing with test-properties (test database) file

I had a project on "spring boot 2" and I want to test it.
Table:
#Entity
#Table(name = "Contract")
public class Contract extends ADBObjectWithID<ContractBean>
{
#NotBlank
#Size(max = 512)
private String name;
#Size(max = 2056)
private String comment;
#Override
public ContractBean toBean()
{
return new ContractBean(getId(), getName(), getComment());
}
}
Repository is CrudRepository<Contract, Long>:
Service:
#Service
public class ContractServiceImpl implements ContractService
{
private ContractRepository contractRepository;
public ContractServiceImpl(ContractRepository contractRepository)
{
this.contractRepository = contractRepository;
}
#Override
#Transactional
public Contract saveObject(ContractBean contractBean)
{
Contract contract;
if (contractBean.getId() == null)
{
contract = new Contract();
}
else
{
contract = findById(contractBean.getId()).orElseThrow(() -> new NullPointerException("Contract not found"));
}
contract.setName(contractBean.getName());
contract.setComment(contractBean.getComment());
return contractRepository.save(contract);
}
#Override
#Transactional
public void deleteObject(ContractBean contractBean)
{
}
#Override
public Optional<Contract> findById(Long id)
{
return contractRepository.findById(id);
}
}
I wanting to test "Service" layer and testing it in the test database. Parameters of the test database available in the "application-test.properties", but I running test, "SpringBoot" used the real database from "application.properties".
Test:
#RunWith(SpringRunner.class)
#SpringBootTest
public class ContractTest
{
#Autowired
private ContractService contractService;
#Test
public void createContract()
{
String name = "Contract name";
String comment = "Contract comment";
ContractBean contractBean = new ContractBean();
contractBean.setName(name);
contractBean.setComment(comment);
Contract contract = contractService.saveObject(contractBean);
Assert.assertEquals(name, contract.getName());
Assert.assertEquals(comment, contract.getComment());
contractBean = contract.toBean();
Assert.assertEquals(name, contractBean.getName());
Assert.assertEquals(comment, contractBean.getComment());
}
}
Pls, tell me, how do I switch to the test base? I trying #PropertySource("classpath:application-test.properties") and #TestPropertySource("classpath:application-test.properties"), but not work
Run with Spring Profile test.
-Dspring.profiles.active=test
You can add the default profile as test into your application.yml to pick it automatically.
spring:
profiles.active: test

How to delete record in MongoDB using Spring Data

I want to delete an record based on Id in Spring.
but in database id value is object
EX:-
id: Object(34562341112313)
How to delete this record in Spring?
You do like this:
public void deleteRecord() {
MongoOperations mongoOperation = (MongoOperations) ctx.getBean("mongoTemplate");
Query searchQuery = new Query(Criteria.where("id").is(34562341112313));
mongoOperation.remove(searchQuery, Your_entity_class.class);
logger.info("Delete success");
}
This is my realistic example:
/**
* Delete by condition(s).
*/
public void deleteJob() {
MongoOperations mongoOperation = (MongoOperations) ctx.getBean("mongoTemplate");
Query searchQuery = new Query(Criteria.where("company").is("DCV"));
mongoOperation.remove(searchQuery, Job.class);
logger.info("Đã xóa các công việc đăng bởi DCV.");
}
Source: https://github.com/SmartJobVN/MongoDB_SpringDataMongo/blob/master/src/main/java/vn/smartJob/jobs/MongoSpringJavaConfigApplication.java#L132
Reference: http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/
You should delete it like this:
#Repository
public class AppDaoClass{
#Autowired
MongoTemplate mongoTemplate;
#Override
public void deleteSomething(String somethingId) {
mongoTemplate.remove(Query.query(Criteria.where("somethingId").is(somethingId)), Ticket.class);
}
}
The first "somethingId" is the name you gave it in your model, and the second somethingId is for the Parametar you are giving in you method.
And your Domain Model:
#Document
public class Model {
#Id
private String somethingId;
private String someName;
private String someOtherName;
}
Be sure to user proper annotations for your classes #Document and #Repository. And add an #Id annotation to your ID field.
Hope this helps.
This is the way you can delete records in spring data mongoDB using MongoTemplate
WriteResult writeResult=mongoTemplate.remove(query,"collection_name");
OR
WriteResult writeResult=mongoTemplate.remove(query,EntityClassName.class);
You can also use repository Pattern
#Document(collection = "user")
public class User {
#Id
private String id;
private String username;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
#Repository
public interface UserRepository extend MongoRepository<User, String>{
public void delete(String id);
public void delete(User user);
public void deleteByUsername(String username);
}
you can use these method anywhere to delete records also u can write your custom methods
#Query(value = "{'_id' : ?0}", delete = true)
void deleteById(String id);

Update Web Service using REST API in Spring Hibernate

I am working with API's and I have to make the update web service. I have tried many ways but I am unable to fetch the desired result.
My domain class is;
#Entity
#Table(name="package")
public class Package{
private Integer packageId;
private String packageName;
private String description;
private Date validFrom;
private Date validUpto;
public enum Status{Active,Inactive}
private Status status;
#JsonBackReference
private Set<HospitalInformation> hospitalInformation=new HashSet<HospitalInformation>();
//getters and setters
My Dao Layer is
#Override
#Transactional(propagation=Propagation.REQUIRED)
public boolean updatePackage(Integer packageId,String packageName,String description,Date validFrom,Date validUpto, Status status) throws Exception {
Session session=sessionFactory.openSession();
Transaction tx= session.beginTransaction();
Package packages=hospitalDao.findByPackageId(packageId);
if(packages!=null){
packages.setPackageName(packageName);
packages.setDescription(description);
packages.setValidFrom(validFrom);
packages.setValidUpto(validUpto);
packages.setStatus(status);
session.saveOrUpdate(packages);
return true;
}else{
return false;
}
My service layer is
#Override
public boolean updatePackageInfo(Integer packageId,String packageName,String description,Date validFrom,Date validUpto, Status status) throws Exception {
return updateDao.updatePackage(packageId, packageName, description, validFrom, validUpto, status);
}
My Controller class has compilation errors:
#Controller
#RequestMapping("/update")
public class UpdateRecordController {
#Autowired
private UpdateService updateService;
static final Logger logger=Logger.getLogger(RestController.class);
#RequestMapping(value="/package", method= RequestMethod.PUT,consumes=MediaType.APPLICATION_JSON_VALUE,produces=MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody Status updatePackageIfo( #RequestParam("Id") Integer Id){
Package packages=new Package();
try{
if(updateService.updatePackageInfo(Id)); //Error {
return new Status(1,"Successfylly Updated with Package Id "+packages.getPackageId());
}else{
return new Status(0,"Failed. Enter a valid packageId");
}
}catch(Exception e){
e.printStackTrace();
return new Status(0,e.getMessage());
}
}
}
Having checked all the links regarding Update Web Service, I couldn't find anything useful on Google. So i need solution of how to make Update Web service.

Hibernate automatic versioning not working (with Spring)

I am trying to use the automatic versioning of Hibernate but when the update method f of the Session is called I do not see the version field in the where clause of the query nor is the version incremented in the database. I am doing something fundamentally wrong probably, but what? Is calling getCurrentSession of sesssionFactory an issue?
I have the following entity class:
package dslibweb.model;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;
#Entity
#Table(name = "dsXCT_Recalls")
public class DsXCT_Recalls {
#Id
public String recallId;
public int version;
public String status;
//...... more properties.....
#Version
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public String getRecallId() {
return recallId;
}
public void setRecallId(String recallId) {
this.recallId = recallId;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
My controller:
package recalls.controller;
#Controller
public class RecallsDataController {
#Autowired
RecallsService recallsManager;
#Autowired
AuthenticationService authService;
private static final Logger logger = Logger.getLogger(RecallsDataController.class);
private static final String SAVE_RECALLS = "MODIFY XCT RECALLS";
RecallsGrid recalls;
#RequestMapping(value = "/showRecallsGrid")
#ResponseBody
public RecallsGrid showRecallsGrid( HttpSession session, HttpServletResponse response) {
recalls = recallsManager.getRecallsDataGrid((String) session.getAttribute("socketToken"), new GridFilters(0, 0, "", "", "", "", ""));
if (recalls.getError() == null || recalls.getError().equals("")) { // no error
return recalls;
} else {
try {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, recalls.getError());
} catch (IOException e) {
e.printStackTrace();
}
return recalls;
}
}
#RequestMapping(value = "/saveRecalls" , method= RequestMethod.POST)
#ResponseBody
public String saveRecalls( HttpSession session, #RequestParam(value="ids[]", required = false) String [] ids, #RequestParam(value="statuses[]", required = false) String [] statuses){
boolean result = authService.validateUserAction((String) session.getAttribute("socketToken"), SAVE_RECALLS);
if(result)
return recallsManager.saveRecalls(ids, statuses, recalls);
else
return "You do not have authority to perform this action.";
}
}
Where I retrieve a collection of DsXCT_Recalls and show them to the user. The collection is stored in the controller. The user then changes status in one or more entities and I call the saveRecalls method of the recallManager which creates a list of only the changed entities (comparing with the collection stored in the controller).
The recallsManager (service layer) is:
package recalls.service.defaultimpl;
#Service("recallManager")
public class HibernateRecallsDataService implements RecallsService {
#Autowired
JsonRpcRequest jsonReq;
#Autowired
JsonRpcSocketWriterReader socketWriterReader;
#Autowired
JsonRpcRequestConstructor reqConstructor;
#Autowired
RecallsDao hibernateRecallsDao;
private static final Logger logger = Logger.getLogger(HibernateRecallsDataService.class);
#Transactional
public RecallsGrid getRecallsDataGrid(String socketToken, GridFilters filters) {
List<DsXCT_Recalls> recalls = hibernateRecallsDao.findRangeOfRecordsFiltered(filters);
return new RecallsGrid(recalls);
}
#Transactional()
public String saveRecalls(String[] ids, String[] statuses, RecallsGrid recalls) {
List<DsXCT_Recalls> recallList = recalls.getRecalls();
List<DsXCT_Recalls> updatedRecallList = new ArrayList<DsXCT_Recalls>();
for (int i = 0; i < ids.length; i++) {
for (DsXCT_Recalls recall : recallList) {
if (recall.recallId.equals(ids[i])) { // recall is found in the list
if (!statuses[i].equals(recall.getStatus())) { // status has changed
recall.setStatus(statuses[i]);
updatedRecallList.add(recall);
}
}
}
}
return hibernateRecallsDao.saveAll(updatedRecallList);
}
}
The saveAll method of my DAO calls one update method of hibernate session by entity changed:
package recalls.dao.hibernate;
#Repository
public class HibernateRecallsDao implements RecallsDao {
#Autowired(required = true)
#Resource(name = "mySessionFactory")
private SessionFactory sessionFactory;
#SuppressWarnings("unchecked")
public List<DsXCT_Recalls> findRangeOfRecordsFiltered(GridFilters filters) {
return sessionFactory.getCurrentSession().createQuery("from DsXCT_Recalls r WHERE SID = 0 ORDER BY Org, Bank, BIC, SetlDate").list();
}
public String saveAll(List<DsXCT_Recalls> recallList){
int count = 0;
for(DsXCT_Recalls recall:recallList){
sessionFactory.getCurrentSession().update(recall);
count++;
}
return count + " recalls were modified.";
}
}
So apparently the #Version must be above the attribute declaration and not above the getter method.. I am sure I saw this somewhere though. So much time wasted :(

LazyInitializationException encountered when using load instead of get with Hibernate

I am using JPA, Hibernate and Spring MVC. In the controller class all the methods works greatly. When I test them in the web browser the public String getModuleFormation(long id) method, that returns an object, and it gives me the following error:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
as a root cause, but yesterday I tried it, and it worked without problem in the localhost:45045/GestionModules/detail/xx URL.
What could cause this problem?
My detail.jsp:
<c:if test="${!empty detailModule}">
${detailModule.idModule}
${detailModule.libModule}
</c:if>
POJO Class + JPA :
#Entity
#Table(name="ModuleFormation")
public class ModuleFormation {
private long idModule;
private String libModule;
public ModuleFormation() {
// TODO Auto-generated constructor stub
}
public ModuleFormation(String libModule) {
this.libModule = libModule;
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "seqModule")
#SequenceGenerator(name="seqModule", sequenceName = "seqModuleFormation")
#Column(name="idModule")
public long getIdModule() {
return this.idModule;
}
public void setIdModule(long idModule) {
this.idModule = idModule;
}
#Column(name="libModule", nullable=false, length = 100)
public String getLibModule() {
return this.libModule;
}
public void setLibModule(String libModule) {
this.libModule = libModule;
}
}
DAO Class :
#Repository
public class ModuleFormationDAOImpl implements ModuleFormationDAO {
#Autowired
private SessionFactory sessionFactory;
public void ajouterModuleFormation(ModuleFormation module) {
sessionFactory.getCurrentSession().save(module);
}
public void supprimerModuleFormation(long idModule) {
ModuleFormation module = (ModuleFormation) sessionFactory.getCurrentSession().load(ModuleFormation.class, idModule);
if(module != null)
sessionFactory.getCurrentSession().delete(module);
}
public List<ModuleFormation> listModuleFormation() {
return sessionFactory.getCurrentSession().createQuery("from ModuleFormation")
.list();
}
public ModuleFormation getModuleFormation(long idModule) {
return (ModuleFormation) sessionFactory.getCurrentSession().load(ModuleFormation.class, idModule);
}
public void majModuleFormation(ModuleFormation module) {
sessionFactory.getCurrentSession().merge(module);
}
}
Service Class :
#Service
public class ModuleFormationServiceImpl implements ModuleFormationService {
#Autowired
private ModuleFormationDAO moduleDao;
#Transactional
public void ajouterModuleFormation(ModuleFormation module) {
moduleDao.ajouterModuleFormation(module);
}
#Transactional
public void supprimerModuleFormation(long idModule) {
moduleDao.supprimerModuleFormation(idModule);
}
#Transactional
public List<ModuleFormation> listModuleFormation() {
return moduleDao.listModuleFormation();
}
#Transactional
public ModuleFormation getModuleFormation(long idModule) {
return moduleDao.getModuleFormation(idModule);
}
#Transactional
public void majModuleFormation(ModuleFormation module) {
moduleDao.majModuleFormation(module);
}
}
Controller Class :
#Controller
public class ModuleFormationController {
#Autowired
private ModuleFormationService moduleService;
#RequestMapping("/module")
public String listModulesFormations(Map<String, Object> map) {
map.put("module", new ModuleFormation());
map.put("moduleList", moduleService.listModuleFormation());
return "module";
}
#RequestMapping(value = "/ajouter", method = RequestMethod.POST )
public String ajouterModuleFormation(#ModelAttribute("module")
ModuleFormation module,BindingResult result) {
moduleService.ajouterModuleFormation(module);
return "redirect:/module";
}
#RequestMapping(value = "/supprimer/{idModule}")
public String supprimerModuleFormation(#PathVariable("idModule")
long idModule) {
moduleService.supprimerModuleFormation(idModule);
return "redirect:/module";
}
#RequestMapping(value= "/detail/{idModule}")
public String getModuleFormation(#PathVariable("idModule")
long idModule,Map<String, Object> map) {
map.put("detailModule", moduleService.getModuleFormation(idModule));
return "/detail";
}
#RequestMapping(value= "/detail/modifier", method = RequestMethod.POST )
public String majModuleFormation(#ModelAttribute("detailModule")
ModuleFormation module, BindingResult result) {
moduleService.majModuleFormation(module);
return "detail/{idModule}";
}
}
The Javadoc on the Hibernate Session#load(Class, Serializable) method says:
Return the persistent instance of the given entity class with the given identifier,
assuming that the instance exists. This method might return a proxied instance that
is initialized on-demand, when a non-identifier method is accessed.
When you access a property on the object in your JSP the session which loaded the object has been closed.
Use Session#get(Class, Serializable) to ensure that you don't load a proxy.
Instead of sessionFactory.getCurrentSession().load(ModuleFormation.class, idModule), have you tried sessionFactory.getCurrentSession().get(ModuleFormation.class, idModule)?

Categories