SQL Server Why does a SQL table record a null value for datetime, if one is passed in from a frontend?

3qpi33ja  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(106)

I have a React frontend, from which an activity object is passed in to be recorded into a SQL table. This is the code for it:

let lid = dataPoints[0]
         let pid = dataPoints[1]
         let spid = dataPoints[2]
         let qasid = dataPoints[3]
         let sid = dataPoints[4]
         cid = dataPoints[5] //already declared in line 443
         let atid = 0
         let datetime2 = new Date(timestamp.slice(0, 24))
         
         //let datetime = datetime2.toString(); // tried with ISOString
         let datetime = datetime2
         
         console.log("Sliced date and time is ", datetime)
            
         
         let activity = JSON.stringify({lid, pid, spid, qasid, sid, cid, atid, datetime})
         
         // submit the activities object to the database
          const resActivity = userService.createActivitiesRecord(activity)

This is the contents of the activity object before it gets sent off, with a bunch of confirmations before:

After this, Axios handles the request and send it off to the database where it records everything, but the datetime - this being the last column in the screenshot:

Axios is the connecting tissue in the UserServices.js file:

createActivitiesRecord(activity) {

    return axios.post("http://projecturl/newactivity", JSON.parse(activity)

 }

Without parsing is a JSON, the server returns a 415 error.

This is what Apache Tomcat 9 is doing when recording the entry - it takes the datetime value, casts it as date and gives it a null value, even if I did try to cast it as such from the frontend in the first place.

UPDATE

One other thing I've noticed is that I can delete the datetime column entirely from the table, and remove it as a field from the model, and the frontend - de facto eveywhere - and SQL will still throw an error about an invalid column name when I go to make a record, with the fact that the column is already gone, it will still look for it.

The backend is in Spring Boot and I am using JPA as the mechanism to pass data to the database.

I've tried a number of approaches:

  1. Deconstruct the activity object into its constituent variables, pass them into the backend one by one and use the @Query annotation to the effect of:

@Query(value = "Insert into activities (lid, pid, spid, qasid, sid, cid, atid, datetime) values (:lid, :pid, :spid, :qasid, :sid, :cid, atid, :datetime)"

OR

@Query(value = "Insert into activities (lid, pid, spid, qasid, sid, cid, atid, datetime) values (:lid, :pid, :spid, :qasid, :sid, :cid, atid, CURRENT_TIMESTAMP)"

Likewise, I tried with to do an UPDATE as well, but in all these cases, the Spring Boot API failed to even launch due to a NullPointerException, which I understood to mean the lack of passed in values for these variables.

Running these queries within SQL SMSS, however, and everything records correctly.

I've tried cleaning the cache in Firefox, the STS4 IDE and the SQL Server database (for the record, I am using SQL 19) to no effect.

Another thing that I noticed is that I can change the data type of the column to any one of varchar, datetime, timestamp , but it does not change anything.

I've also tried playing with the format in the frontend, backend and in SQL - of course, ensuring consistency - but that didn't help. Using a String format for everything also failed. In the model, I also attempted to use Date , Java's own Timestamp class, and String , but nothing.

I did come across SO and elsewhere, researching the issue, that it was not possible to pass a timestamp through Java to SQL, because the DB engine has its own mechanism for generating one in a dedicated column when a record is made, so that inspired the @Query attempts.

I also did try to use the gettime() function as a default value for the column, but that also led to nothing.

Currently, it passes data in using a Repository - Service - Controller - Model package structure. Codes are below and I've omitted imports for brevity.

ActivityRepository.java:

import com.example.demo.model.Activities;

public interface ActivitiesRepository extends JpaRepository<Activities, Integer>{

    
}

ActivitiesService.java:

@Service
public class ActivitiesService {
    
    @Autowired
    ActivitiesRepository activitiesRepo;
    
    public List<Activities> getAllActivities() {
        
        List<Activities> activities = new ArrayList<>();
        
        activitiesRepo.findAll().forEach(activityItem -> activities.add(activityItem));
        
        return activities;
    }
    
    public void saveOrUpdate(Activities _activity) {
        activitiesRepo.save(_activity);
        //activitiesRepo.insertTimestamp();
    }
    
    public Activities findById(int id) {
        return activitiesRepo.findById(id).get();
    }

    public void deleteAll() {
        activitiesRepo.deleteAll();
    }
    
    public void deleteById(int id) {
        activitiesRepo.deleteById(id);
    }
    
}

ActivitiesController.java:

@RestController
@CrossOrigin
public class ActivitiesController {
    
    @Autowired
    ActivitiesService activitiesService;
    
    @GetMapping("/activities") 
    public List<Activities> getActivities() {
        return activitiesService.getAllActivities();
    }
    
    @PostMapping("/activities-item")
    public void addActivity(@RequestBody Activities activity) {
        System.out.println("Activity is " + activity);
        activitiesService.saveOrUpdate(activity);
    }
    
    @GetMapping("/activities/{id}")
    public Activities getActivitiesItem(@PathVariable("id") int id) {
        return activitiesService.findById(id);
    }
    
    @PutMapping("/activities")
    public void updateActivity(@RequestBody Activities activity) {
        activitiesService.saveOrUpdate(activity);
    }
    
    @DeleteMapping("/activities/{id}")
    public void deleteById(@PathVariable("id") int id) {
        activitiesService.deleteById(id);
    }

}

Activities.java:

@Entity
@Table(name="activities")
public class Activities {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int AID;
    
    @Column(name="LID")
    private int LID;
    
    @Column(name="PID")
    private int PID;
    
    @Column(name="SPID")
    private int SPID;
    
    @Column(name="QASID")
    private int QASID;
    
    @Column(name="SID")
    private int SID;
    
    @Column(name="CID")
    private int CID;
    
    @Column(name="ATID")
    private int ATID;
    
    @Column(name="datetime")
    private String datetime;
    
// getters/setters and constructors follow this

Thank you in advance!

icnyk63a

icnyk63a1#

Well, the problem is solved. The code itself is fine - what was wrong is that the request path was using a deployed version of the project, not the development one. As a result, changes in the code required the project to be recompiled and redeployed for them to reflect. It is working fine now.

Therefore - if you're testing, have a sandbox in your local environment that emulates the production environment, and define your URLs accordingly, or compile and redeploy with your changes.

相关问题