使用RestTemplate和Entity Manager映射PostgreSQL数据库的对象

发布于 2025-02-07 19:33:36 字数 9684 浏览 1 评论 0原文

我正在创建一个Spring Boot应用程序,其中我必须在其中消耗此 api ,将其json内容添加到一个PostgreSQL DB并添加了一个时间戳列,以捕获并保存数据传输的确切点。时间戳列不存在于进入的JSON文档中。在下面,我显示了我的代码以及邮政屏幕截图,该屏幕截图映射时间戳变量但返回空。

我搜索在这里a href =“ https://www.baeldung.com/spring-data-entitymanager” rel =“ nofollow noreferrer”>在这里,看到我必须使用实体经理。在我的配置类中,我创建了EntityManagerFactory,然后创建了EntityManager,但是我得到了“无持久性提供者的EntityManager”,因此我评论了该代码(我留下来展示我的尝试)。然后,我搜索在这里,看到我需要persistance.xml文件。

我还搜索了后者,发现Spring Boot不再需要这种文件,但是我仍然在如何实现目标方面遇到困难。

任何建议都将有用。

PS我打算将ID变量替换为Timestamp One,作为主要键。

主要类

package com.andrekreou.iot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@SpringBootApplication
@EnableJpaRepositories
public class IotApplication {

    public static void main(String[] args) {
        SpringApplication.run(IotApplication.class, args);
    }
}

EntityClass

package com.andrekreou.iot.bitpay;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.*;
import java.time.LocalDateTime;

//This class is responsible for mapping the key variables from
//the JSON array to be imported. The name keys from JSON have
//to be exactly the same as here, in order for data to be fetched.


//Don't forget to apply Lombok, at the end of the project as appendix!!!
@Entity
@Table
@JsonIgnoreProperties(ignoreUnknown = true)
public class BitPayRates {
    @Id
    @SequenceGenerator(
            name = "bitpay_sequence",
            sequenceName = "bitpay_sequence",
            allocationSize = 1
            )
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "bitpay_sequence"
    )
    private Integer id;
    private String code;
    private String name;
    private Long rate;

    private java.time.LocalDateTime timestamp;

    protected BitPayRates() {
    }

    public BitPayRates(String code, String name, Long rate, LocalDateTime timestamp) {
        this.code = code;
        this.name = name;
        this.rate = rate;
        this.timestamp = timestamp;
    }

    // Getters and setters

    @Override
    public String toString() {
        return "BitPayRates{" +
                "id=" + id +
                ", code='" + code + '\'' +
                ", name='" + name + '\'' +
                ", rate=" + rate +
                '}';
    }
}

控制器类

package com.andrekreou.iot.bitpay;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

//The controller for the project, which handles HTTP requests
@RestController
public class RestSpringBootController {

    //Dependency injection to connect with Service layer
    private final Service service;

    @Autowired
    public RestSpringBootController(Service service) {
        this.service = service;
    }

    @GetMapping(path = "/bitpay")
    public List<List<BitPayRates>> getData(){
        return service.getData();
    }
}

服务类

package com.andrekreou.iot.bitpay;

import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collections;
import java.util.List;

//The service layer class for business logic implementation
@org.springframework.stereotype.Service
public class Service {

    //Dependency injection to connect with Repository layer
    private final BitPayRatesRepo bitPayRatesRepo;

    @Autowired
    public Service(BitPayRatesRepo bitPayRatesRepo) {
        this.bitPayRatesRepo = bitPayRatesRepo;
    }

    public List<List<BitPayRates>> getData() {
        return Collections.singletonList(bitPayRatesRepo.findAll());
    }
}

存储库接口

package com.andrekreou.iot.bitpay;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

//Interface that multiple classes can use and connects with data JPA
//The JPA is a map that takes the variables mapped in BitPayRates class
//as first parameter and as second, returns the data type of the Id.
@Repository
public interface BitPayRatesRepo
        extends JpaRepository<BitPayRates,Integer> {

}

配置类

package com.andrekreou.iot.bitpay;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import java.time.LocalDateTime;
import java.util.List;

//The configuration class to fetch data from url and execute the insertion
//of the data into the PostgreSQL database
@Configuration
public class BitPayRatesConfig {

    @Bean
    CommandLineRunner commandLineRunner(BitPayRatesRepo bitPayRatesRepo) {
        return args -> {




/*            EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-persistence-unit");
            EntityManager em = emf.createEntityManager();
            em.getTransaction().begin();
            BitPayRates b = new BitPayRates();
            b.setTimestamp(LocalDateTime.now());
            b.setTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
                    .parse("2017-11-15 15:30:14.332"));

            em.persist(b);*/


            String url = "https://bitpay.com/api/rates";
            RestTemplate restTemplate = new RestTemplate();

            ResponseEntity<List<BitPayRates>> postEntity = restTemplate.exchange(
                url,
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<>() {
                });


        List<BitPayRates> results = postEntity.getBody();
        bitPayRatesRepo.saveAll(results);
        System.out.println(results);
        };
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.andrekreou</groupId>
    <artifactId>iot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>iot</name>
    <description>MSc Thesis</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.4.0-b180830.0359</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

I am creating a Spring Boot application in which I have to consume this API, add it's JSON contents to a PostgreSQL DB and adding also a timestamp column to capture and save the exact point of data transmission. The timestamp column doesn't exist at the incoming JSON document. Below I am showing my code as well as a POSTMAN screenshot which maps the timestamp variable but returns null.

I searched here and here and saw that I have to use an Entity Manager. At my configuration class, I created the EntityManagerFactory and then EntityManager but I am getting the "No Persistence Provider for EntityManager", thus I commented that piece of code (I left it to showcase my try). Then I searched here, and saw that I need the persistance.xml file.

I also searched about the latter and discovered that Spring Boot doesn't require that kind of file anymore, but still I am having trouble at how to approach my goal.

Any kind of advice, would be useful.

P.S. I am planning to replace the id variable with the timestamp one, as primary key.

POSTMAN Results

Main Class

package com.andrekreou.iot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@SpringBootApplication
@EnableJpaRepositories
public class IotApplication {

    public static void main(String[] args) {
        SpringApplication.run(IotApplication.class, args);
    }
}

EntityClass

package com.andrekreou.iot.bitpay;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.*;
import java.time.LocalDateTime;

//This class is responsible for mapping the key variables from
//the JSON array to be imported. The name keys from JSON have
//to be exactly the same as here, in order for data to be fetched.


//Don't forget to apply Lombok, at the end of the project as appendix!!!
@Entity
@Table
@JsonIgnoreProperties(ignoreUnknown = true)
public class BitPayRates {
    @Id
    @SequenceGenerator(
            name = "bitpay_sequence",
            sequenceName = "bitpay_sequence",
            allocationSize = 1
            )
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "bitpay_sequence"
    )
    private Integer id;
    private String code;
    private String name;
    private Long rate;

    private java.time.LocalDateTime timestamp;

    protected BitPayRates() {
    }

    public BitPayRates(String code, String name, Long rate, LocalDateTime timestamp) {
        this.code = code;
        this.name = name;
        this.rate = rate;
        this.timestamp = timestamp;
    }

    // Getters and setters

    @Override
    public String toString() {
        return "BitPayRates{" +
                "id=" + id +
                ", code='" + code + '\'' +
                ", name='" + name + '\'' +
                ", rate=" + rate +
                '}';
    }
}

Controller Class

package com.andrekreou.iot.bitpay;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

//The controller for the project, which handles HTTP requests
@RestController
public class RestSpringBootController {

    //Dependency injection to connect with Service layer
    private final Service service;

    @Autowired
    public RestSpringBootController(Service service) {
        this.service = service;
    }

    @GetMapping(path = "/bitpay")
    public List<List<BitPayRates>> getData(){
        return service.getData();
    }
}

Service Class

package com.andrekreou.iot.bitpay;

import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collections;
import java.util.List;

//The service layer class for business logic implementation
@org.springframework.stereotype.Service
public class Service {

    //Dependency injection to connect with Repository layer
    private final BitPayRatesRepo bitPayRatesRepo;

    @Autowired
    public Service(BitPayRatesRepo bitPayRatesRepo) {
        this.bitPayRatesRepo = bitPayRatesRepo;
    }

    public List<List<BitPayRates>> getData() {
        return Collections.singletonList(bitPayRatesRepo.findAll());
    }
}

Repository Interface

package com.andrekreou.iot.bitpay;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

//Interface that multiple classes can use and connects with data JPA
//The JPA is a map that takes the variables mapped in BitPayRates class
//as first parameter and as second, returns the data type of the Id.
@Repository
public interface BitPayRatesRepo
        extends JpaRepository<BitPayRates,Integer> {

}

Configuration Class

package com.andrekreou.iot.bitpay;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import java.time.LocalDateTime;
import java.util.List;

//The configuration class to fetch data from url and execute the insertion
//of the data into the PostgreSQL database
@Configuration
public class BitPayRatesConfig {

    @Bean
    CommandLineRunner commandLineRunner(BitPayRatesRepo bitPayRatesRepo) {
        return args -> {




/*            EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-persistence-unit");
            EntityManager em = emf.createEntityManager();
            em.getTransaction().begin();
            BitPayRates b = new BitPayRates();
            b.setTimestamp(LocalDateTime.now());
            b.setTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
                    .parse("2017-11-15 15:30:14.332"));

            em.persist(b);*/


            String url = "https://bitpay.com/api/rates";
            RestTemplate restTemplate = new RestTemplate();

            ResponseEntity<List<BitPayRates>> postEntity = restTemplate.exchange(
                url,
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<>() {
                });


        List<BitPayRates> results = postEntity.getBody();
        bitPayRatesRepo.saveAll(results);
        System.out.println(results);
        };
    }
}

POM.XML

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.andrekreou</groupId>
    <artifactId>iot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>iot</name>
    <description>MSc Thesis</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.4.0-b180830.0359</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

_畞蕅 2025-02-14 19:33:36

好吧,据我所知,时间戳永远不会实例化。是的,您有一个私有localdateTime Timestamp;,但是您永远不会从中创建一个对象(现在应该是();

您在注释的代码中都有它,但是在工作中,它丢失了。

没有对象,无数据,db中的null。

Well, as far as I can see the timestamp is never instantiated. Yes you have a private LocalDateTime timestamp;, BUT you never create an object from it (which should be now();

You have it in commented out code, but in working one it's missing.

No object, no data, null in DB.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文