【问题标题】:fetching the data with spring jpa使用 spring jpa 获取数据
【发布时间】:2020-02-13 05:05:20
【问题描述】:

我还是java和spring的初学者,我已经在mysql中存储了名为Offers的表,我试图逐行获取数据where the Status == 0,我的表看起来像:

-------------+------------+------------+------------+--------------+--------+--------+--------+--------+--------------+
| Msisdn      | Entry_Date | Start_Date | End_Date   | Service_Type | Status | Parm_1 | Parm_2 | Parm_3 | Process_Date |
+-------------+------------+------------+------------+--------------+--------+--------+--------+--------+--------------+
| 7777777777  | 2019-01-11 | 2019-02-15 | 2019-03-03 | 1            |      1 | 1      | 1      | 1      | 2019-10-15   |
| 7888888899  | 2019-01-11 | 2019-02-12 | 2019-03-03 | 1            |      0 | 1      | 1      | 1      | 2019-10-15   |
| 799999999   | 2019-01-11 | 2019-02-10 | 2019-03-03 | 1            |      0 | 1      | 1      | 1      | 2019-10-15   |
| 79111111111 | 2019-01-28 | 2019-02-27 | 2019-03-03 | 1            |      0 | 1      | 1      | 1      | 2019-10-15   |
+-------------+------------+------------+------------+--------------+--------+--------+--------+--------

当我尝试运行我的代码时,它的返回

org.springframework.beans.factory.BeanCreationException: 错误 创建在类路径中定义的名称为“entityManagerFactory”的bean 资源 [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: 调用 init 方法失败;嵌套异常是 org.hibernate.AnnotationException:没有为实体指定标识符: com.example.accessingdatajpa.Offers

优惠

package com.example.accessingdatajpa;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;


@Entity
public class Offers {

    @GeneratedValue(strategy=GenerationType.AUTO)
    private String Msisdn;
    private String Entry_Date;
    private String Start_Date;
    private String End_Date;
    private String Service_Type;
    private String Status;
    private String Parm_1;
    private String Parm_2;
    private String Parm_3;
    private String Process_Date;

    protected Offers() {}

    public Offers(String Msisdn, String Entry_Date, String Start_Date, String End_Date, String Service_Type, String Status, String Parm_1 ,String Parm_2, String Parm_3, String Process_Date) {
        this.Msisdn = Msisdn;
        this.Entry_Date = Entry_Date;
        this.Start_Date = Start_Date;
        this.End_Date = End_Date;
        this.Service_Type = Service_Type;
        this.Status = Status;
        this.Parm_1 = Parm_1;
        this.Parm_2 = Parm_2;
        this.Parm_3 = Parm_3;
        this.Process_Date = Process_Date;
    }

    @Override
    public String toString() {
        return String.format(
                "Offers[Msisdn='%s', Entry_Date='%s', Start_Date='%s', End_Date='%s', Service_Type='%s', Status='%s', Parm_1='%s', Parm_2='%s', Parm_3='%s',Process_Date='%s']",
                Msisdn, Entry_Date, Start_Date, End_Date, Service_Type, Status, Parm_1,Parm_2,Parm_3,Process_Date);
    }

    public String getMsisdn() {
        return Msisdn;
    }

    public String getProcess_Date() {
        return Process_Date;
    }

    public String getEntry_Date() {
        return Entry_Date;
    }

    public String getStart_Date() {
        return Start_Date;
    }

    public String getEnd_Date() {
        return End_Date;
    }

    public String getService_Type() {
        return Service_Type;
    }

    public String getStatus() {
        return Status;
    }

    public String getParm_1() {
        return Parm_1;
    }

    public String getParm_2() {
        return Parm_2;
    }

    public String getParm_3() {
        return Parm_3;
    }
}

OffersRepository

package com.example.accessingdatajpa;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

public interface OffersRepository extends CrudRepository<Offers, String> {

    List<Offers> findByStatus(String Status);

    Offers findByMsisdn(String Msisdn);
}

访问DataJpaApplication

package com.example.accessingdatajpa;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class AccessingDataJpaApplication {

    private static final Logger log = LoggerFactory.getLogger(AccessingDataJpaApplication.class);

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

    @Bean
    public CommandLineRunner demo(OffersRepository repository) {
        return (args) -> {

            // fetch by status =0
            log.info("Offers found with findByStatus('0'):");
            log.info("--------------------------------------------");
            repository.findByStatus("0").forEach(on -> {
                log.info(on.toString());
            });
            log.info("");
        };
    }

}

测试文件

package com.example.accessingdatajpa;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@DataJpaTest
public class OffersRepositoryTests {
    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private OffersRepository offer;

    @Test
    public void testFindByStatus() {
        Offers Offer = new Offers();
        entityManager.persist(Offer);

        List<Offers> findByStatus = offer.findByStatus(Offer.getStatus());

        assertThat(findByStatus).extracting(Offers::getStatus).containsOnly(Offer.getStatus());
    }
}

【问题讨论】:

  • 你需要像@Id @GeneratedValue(strategy=GenerationType.AUTO) private String Msisdn;

标签: java spring hibernate spring-boot jpa


【解决方案1】:

我发现那里的错误很少:

第一

msisdn添加@Id注解

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private String Msisdn;

第二次

OffersRepository添加@Repository注解

@Repository
public interface OffersRepository extends CrudRepository<Offers, String> {

    List<Offers> findByStatus(String Status);

    Offers findByMsisdn(String Msisdn);
}

第三次

OffersRepository 类型的自动装配bean 添加到您的AccessingDataJpaApplication 类并从您的方法public CommandLineRunner demo(OffersRepository repository) 中删除参数OffersRepository repository

@SpringBootApplication
public class AccessingDataJpaApplication {

    private static final Logger log = LoggerFactory.getLogger(AccessingDataJpaApplication.class);

    @Autowired
    private OffersRepository repository;

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

    @Bean
    public CommandLineRunner demo() {
        return (args) -> {

            // fetch by status =0
            log.info("Offers found with findByStatus('0'):");
            log.info("--------------------------------------------");
            repository.findByStatus("0").forEach(on -> {
                log.info(on.toString());
            });
            log.info("");
        };
    }

}

第四次

如果你想使用CommandLineRunner,你需要实现它。您可以通过一种非常简单的方式来实现,只需在您的引导类中实现即可。

AccessingDataJpaApplication.java

@SpringBootApplication
public class AccessingDataJpaApplication implements CommandLineRunner {

    @Autowired
    private OffersRepository repository;

    private static final Logger log = LoggerFactory.getLogger(AccessingDataJpaApplication.class);

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

    @Override
    public void run(String...args) {
        log.info("Offers found with findByStatus('0'):");
        log.info("--------------------------------------------");
        repository.findByStatus("0").forEach(on - >{
            log.info(on.toString());
        });
        log.info("");
    }

}

【讨论】:

  • 上下文初始化期间遇到异常 - 取消刷新尝试:org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为“accessingDataJpaApplication”的bean时出错:通过字段“repository”表示的依赖关系不满足;嵌套异常是 org.springframework.beans.factory.BeanCreationException: Error created bean with
  • name 'offersRepository': init 方法调用失败;嵌套异常是 java.lang.IllegalArgumentException:无法为方法 public abstract java.util.List com.example.accessingdatajpa.OffersRepository.findByStatus(java.lang.String) 创建查询!无法在此 ManagedType [com.example.accessingdatajpa.Offers] 上找到具有给定名称 [status] 的属性
  • 按照惯例,属性通常以小写字母开头。在 Offers 类中将属性 Status 重命名为 statusprivate String status
  • 谢谢它的工作,但问题是它没有在控制台上打印出结果
  • 嗯,那是因为您没有向控制台打印任何内容。如果要使用 CommandLineRunner,则需要实现它。我已经更新了我的答案。看看
【解决方案2】:

优惠没有主键。您必须使用 @Id 注释主键属性

喜欢

@Id
private Integer id;

【讨论】:

  • 每次我运行代码时都会返回此警告:启动 ApplicationContext 时出错。要显示条件报告,请在启用“调试”的情况下重新运行您的应用程序。 2019-10-16 16:13:01.855 错误 16835 --- [main] osboot.SpringApplication:应用程序运行失败 org.springframework.beans.factory.UnsatisfiedDependencyException:创建 com.example 中定义的名称为“demo”的 bean 时出错。 accessdatajpa.AccessingDataJpaApplication:通过方法'demo'参数0表示的不满足的依赖关系;嵌套异常是 org.springframework.beans.factor
【解决方案3】:

你需要这样做:

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private String Msisdn;

【讨论】:

    【解决方案4】:

    您缺少带有@Id 注释的字段。每个@Entity 都需要一个@Id - 这是数据库中的主键。在您的实体类上指定如下注释:

    @Entity
    @Table(name = "OFFERS")
    public class Offers {
    
       @Id
       @GeneratedValue(strategy=GenerationType.AUTO)
       @Column(name = "Msisdn")
       private String Msisdn;
    
       @Column(name = "Entry_Date")   
       private String Entry_Date;
    
       @Column(name = "Start_Date")
       private String Start_Date;
    
       @Column(name = "End_Date")
       private String End_Date;
    
       @Column(name = "Service_Type")
       private String Service_Type;
    
       @Column(name = "Status")
       private String Status;
    
       @Column(name = "Parm_1")
       private String Parm_1;
    
       @Column(name = "Parm_2")
       private String Parm_2;
    
       @Column(name = "Parm_3")
       private String Parm_3;
    
       @Column(name = "Process_Date")
       private String Process_Date;
       //Setters and getters
    }
    

    如果您的列和表名遵循隐式命名策略,则可以不使用注释指定表和列。

    @Id注解的放置标记持久化状态访问 strategy.The 标识符唯一标识该表中的每一行。经过 默认情况下,假设表的名称与名称相同 的实体。显式给出表的名称或指定 关于表的其他信息,我们将使用 javax.persistence.Table 注释。逻辑名称可以是显式的 由用户指定(例如使用@Column 或@Table),也可以是 Hibernate 通过 ImplicitNamingStrategy 隐式确定 合同。

    官方Doc.

    【讨论】:

    猜你喜欢
    • 2020-03-11
    • 2014-08-08
    • 1970-01-01
    • 1970-01-01
    • 2021-08-23
    • 2017-07-06
    • 1970-01-01
    • 2019-11-18
    • 2011-12-17
    相关资源
    最近更新 更多