A
A
Andrey Kovalchuk2016-05-24 20:49:58
Java
Andrey Kovalchuk, 2016-05-24 20:49:58

How to solve the problem with connecting spring-repositories?

Good day. The problem with... that, I don't know what.
I wrote a custom method for the repository and a simple request in it, but that's bad luck: it doesn't get me my record.
The database has a room table and an Index column inside.
Repository with custom method.

public interface RoomRepository extends JpaRepository<Room,Integer> {
    @Query("FROM Room b where b.index = :Index")
    Room findByIndex(@Param("Index") String index);
}

So, sequentially, what from what.
First we have a rest controller:
@RestController
public class StartController {

    @Autowired
    private RoomService roomService;

    @RequestMapping(value = "/start", method = RequestMethod.GET)
    @ResponseBody
    public void startArduinoScan() throws SerialPortException {
        //Попробуем завести наш АрдуиноКоннектер
        ArduinoConfig arduinoConfig = new ArduinoConfig();
        arduinoConfig.arduinoConnection(roomService);
    }

    @RequestMapping(value = "/index/{index}", method = RequestMethod.GET)
    @ResponseBody
    public Room getRoomByIndex(@PathVariable String index){
        return roomService.findByIndex(index);
    }

/index/{index} works, only serialization is not configured there, but this is not relevant, the main thing is that the request is being made.
Digging Deeper
ArduinoConfig.java
@Configuration
@ComponentScan("com.kovalchuk.server")
@EnableJpaRepositories("com.kovalchuk.server.repository")
public class ArduinoConfig {


    private static SerialPort serialPort;

    public static SerialPort getSerialPort() {
        return serialPort;
    }


    public void arduinoConnection(RoomService roomService) throws SerialPortException {
        serialPort = new SerialPort("COM3");

        try{
            serialPort.openPort();
            serialPort.setParams(9600,8,1,0);
            serialPort.setEventsMask(SerialPort.MASK_RXCHAR);
            serialPort.addEventListener(new ArduinoEventsListener());


        }
        catch (SerialPortException ex){
            System.out.println(ex);
        }
    }

}

The moment the method is called.
Date[2] - non-empty, contains the index you are looking for.
@ComponentScan("com.kovalchuk.server")
@EnableJpaRepositories("com.kovalchuk.server.repository")
public class ArduinoEventsListener implements SerialPortEventListener {

    private SerialPort serialPort = ArduinoConfig.getSerialPort();

    @Autowired
    private CommitRepository commitRepository;

    @Autowired
    private RoomRepository roomRepository;




    @Override
    public void serialEvent(SerialPortEvent event) {
        try {
            String buffer = serialPort.readString(15);
            String[] data = buffer.split(":");

            Commit commit = new Commit();

            commit.setTemperature(Double.parseDouble(data[0]));
            commit.setWet(data[1]);
            commit.setDate(new Date());




            Room room = roomRepository.findByIndex(data[2]);

            commit.setRoom(room);

            commitRepository.save(commit);


        } catch (SerialPortException e) {
            e.printStackTrace();
        }
    }

}


entity

package com.kovalchuk.server.entity;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;

@Entity
@Table (name= "room")
public class Room {

    @Id
    @Column(name ="idRoom")
    @GeneratedValue(generator = "increment")
    @GenericGenerator(name = "increment", strategy = "increment")
    private Long id;

    @Column(name="Index")
    private String index;

    @Column(name = "Type")
    private String type;

    @Column(name = "Status")
    private Commit status;

    public Room(String index, String type, Commit status) {
        this.index = index;
        this.type = type;
        this.status = status;
    }

    public Room(String index, String type) {
        this.index = index;
        this.type = type;
    }

    public Room() {
    }

    public Commit getStatus() {
        return status;
    }

    public void setStatus(Commit status) {
        this.status = status;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getIndex() {
        return index;
    }

    public void setIndex(String index) {
        this.index = index;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

Index table
CREATE TABLE `room` (
  `idRoom` bigint(20) NOT NULL AUTO_INCREMENT,
  `Index` varchar(5) NOT NULL,
  `Type` varchar(5) DEFAULT NULL,
  `Status` bigint(20) NOT NULL,
  PRIMARY KEY (`idRoom`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

The problem is clearly in calling Repositories. Why, I can't figure it out.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
A
Alexander Kosarev, 2016-05-25
@mrkovalchuk

You have an identifier of type Long in the entity class, but the repository has Integer in the generic. Perhaps the problem is related to this. In general, yes, if you have Spring Data JPA, then it’s more logical to simply specify the Room findByIndex(String index) method in the interface; without additional annotations.

G
guras256, 2016-05-24
@guras256

you have spring data, what for did you write hql query?

public interface RoomRepository extends JpaRepository<Room, Integer> {
    Room findByIndex(String index);
}

all you need to do is if Room is properly annotated
and yes, name the Index field with a lowercase letter...

R
Ruslan Lopatin, 2016-05-25
@lorus

The problem seems to be related to Commit. Does the Commit table contain data at all?
Maybe we should create Commit inside the serialEvent method, and not as a field of the ArduinoEventListener class? In addition, it is worth registering the ManyToOne annotation for the Room.status field

A
Andrey Kovalchuk, 2016-05-26
@mrkovalchuk

see solution from Alexander Kosarev (above)
***************************************** ******************************************************* **********
I solved the problem, but I'm not sure how correct this approach is.
So, now I declare two services in the controller that work with repositories and put them in ArduinoConfig through the newly created constructor (see below).

package com.kovalchuk.server.controller;

import com.kovalchuk.server.config.arduino.ArduinoConfig;
import com.kovalchuk.server.entity.Room;
import com.kovalchuk.server.services.interf.CommitService;
import com.kovalchuk.server.services.interf.RoomService;
import jssc.SerialPortException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
public class StartController {

    @Autowired
    private RoomService roomService;

    @Autowired
    private CommitService commitService;

    @RequestMapping(value = "/start", method = RequestMethod.GET)
    @ResponseBody
    public void startArduinoScan() throws SerialPortException {
        //Попробуем завести наш АрдуиноКоннектер
        ArduinoConfig arduinoConfig = new ArduinoConfig(roomService,commitService);
        arduinoConfig.arduinoConnection();
    }  

}

In ArduinoConfig I define Service as fields and add two Getters for them. Well, yes, the designer drew the corresponding one.
package com.kovalchuk.server.config.arduino;


import com.kovalchuk.server.services.interf.CommitService;
import com.kovalchuk.server.services.interf.RoomService;
import jssc.SerialPort;
import jssc.SerialPortException;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@Configuration
@ComponentScan("com.kovalchuk.server")
@EnableJpaRepositories("com.kovalchuk.server.repository")
public class ArduinoConfig {


    private static SerialPort serialPort;
    private static RoomService roomService;
    private static CommitService commitService;

    public ArduinoConfig() {
    }

    public ArduinoConfig(RoomService roomService, CommitService commitService) {
        this.roomService = roomService;
        this.commitService = commitService;
    }

    public static RoomService getRoomService() {
        return roomService;
    }

    public static CommitService getCommitService() {
        return commitService;
    }

    public static SerialPort getSerialPort() {
        return serialPort;
    }


    public void arduinoConnection() throws SerialPortException {
        serialPort = new SerialPort("COM3");

        try{
            serialPort.openPort();
            serialPort.setParams(9600,8,1,0);
            serialPort.setEventsMask(SerialPort.MASK_RXCHAR);
            serialPort.addEventListener(new ArduinoEventsListener());


        }
        catch (SerialPortException ex){
            if (serialPort.isOpened()) serialPort.closePort();
        }
    }
}

And this is how the ArduinoEventsListener was transformed, which, using geters, gets our Servics to work with the database.
package com.kovalchuk.server.config.arduino;


import com.kovalchuk.server.entity.Commit;
import com.kovalchuk.server.entity.Room;
import com.kovalchuk.server.services.interf.CommitService;
import com.kovalchuk.server.services.interf.RoomService;
import jssc.SerialPort;
import jssc.SerialPortEvent;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

import java.util.Date;

@ComponentScan("com.kovalchuk.server")
@EnableJpaRepositories("com.kovalchuk.server.repository")
public class ArduinoEventsListener implements SerialPortEventListener {

    private SerialPort serialPort = ArduinoConfig.getSerialPort();
    private RoomService roomService = ArduinoConfig.getRoomService();
    private CommitService commitService = ArduinoConfig.getCommitService();



    @Override
    public void serialEvent(SerialPortEvent event) {
        try {
            String buffer = serialPort.readString(15);
            String[] data = buffer.split(":");

            Commit commit = new Commit();

            commit.setTemperature(Double.parseDouble(data[0]));
            commit.setWet(data[1]);
            commit.setDate(new Date());

            Room room = roomService.findByIndex(data[2]);

            commit.setRoom(room);

            commitService.save(commit);


        } catch (SerialPortException e) {
            e.printStackTrace();
        }
    }

}

The solution allows you to write data to a table without any problems, but I don’t know if it’s right to do this. Maybe it was worth hooking services directly from the controller with getters so as not to stretch them - but how correct is this in relation to the controller itself? It works, but there are still a lot of questions.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question