Spring Boot:使用 Spring Data JPA 读取数据返回不正确的值 [英] Spring Boot: Reading data using Spring Data JPA returns incorrect values

查看:36
本文介绍了Spring Boot:使用 Spring Data JPA 读取数据返回不正确的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的应用程序中使用 Spring Boot.我有一个访问服务层的控制器,该服务层访问我的 Spring Data JPA 的 CrudRepository 实现,它与 Hibernate 交互以从数据库中获取数据.CrudRepository 的以下所有三个实现都返回了错误的对象:

I'm using Spring Boot in my application. I have a controller which accesses the service layer which accesses my implementation of Spring Data JPA's CrudRepository which interacts with Hibernate to fetch data from the database. All three of the following implementations of CrudRepository return incorrect objects:

public class ProductRepositoryImpl implements ProductRepository {

    @Autowired
    private SessionFactory sessionFactory;

    @SuppressWarnings("unchecked")
    public List<Product> findProductBatch(int start, int end) {
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery("from Product");
        query.setFirstResult(start);
        query.setMaxResults(end);
        List<Product> list = query.list();
        return list;
    }

    @SuppressWarnings({ "unused", "unchecked" })
    @Override
    public Iterable<Product> findAll() {
        Session session = sessionFactory.getCurrentSession();
        List<Product> products = session.createQuery("from Product").list();
        Iterable<Product> productIterable = products;
        return products;
    }

    @SuppressWarnings("unchecked")
    public List<Product> findBatch(int start, int end) {
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery("from Product");
        query.setFirstResult(start);
        query.setMaxResults(end);
        List<Product> list = query.list();
        return list;
    }

}

findOne() 方法仅在传递给它的参数为零时才返回记录,而记录的 id 不为零.发送请求时返回以下 JSON 响应:

The findOne() method returns a record only if the parameter passed to it is zero, while the record's id is not zero. The following JSON response is returned upon sending a request:

{
  "productId": 0,
  "name": "xxxxxx",
  "productCategoryId": null,
  "created": 1482655958000,
  "createdBy": null
}

该记录存在于数据库中,但它的 id 为 1,它确实有一个productCategoryId",但由于它没有被注入,所以它返回了 null.

The record exists in the database but its id is 1 and it does have a "productCategoryId" but since it wasn't injected, it returned null.

findAll() 方法返回重复多次的相同记录,而 findBatch() 方法返回类似的响应.

The findAll() method returns the same record repeated many times and the findBatch() method returns a similar response.

其余代码如下:

Product.java:

Product.java:

@Entity
public class Product {

    @Id
    private Integer productId;
    private String name;
    private Integer productCategoryId;
    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "productCategoryId", insertable = false, updatable = false)
    @Autowired
    private ProductCategory productCategory;
    private Date created;
    private Integer createdBy;

    public Product() {
    }

    public Product(Integer productId, String name, ProductCategory productCategory, Integer uomId, Date created, Integer createdBy) {
        this.productId = productId;
        this.name = name;
        this.productCategory = productCategory;
        this.created = created;
        this.createdBy = createdBy;
    }

    public Product(String name, ProductCategory productCategory) {
        this.name = name;
        this.productCategory = productCategory;
    }

    public Integer getProductId() {
        return productId;
    }

    public void setProductId(Integer productId) {
        this.productId = productId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getProductCategoryId() {
        return productCategoryId;
    }

    public void setProductCategoryId(Integer productCategoryId) {
        this.productCategoryId = productCategoryId;
    }

//  public ProductCategory getProductCategory() {
//      return productCategory;
//  }
//
//  public void setProductCategory(ProductCategory productCategory) {
//      this.productCategory = productCategory;
//  }

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    public Integer getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(Integer createdBy) {
        this.createdBy = createdBy;
    }
}

ProductCategory.java:

ProductCategory.java:

    @Entity
    public class ProductCategory {

    @Id
    private Integer productCategoryId;
    private String name;
    private Date created;
    private Integer createdBy;

    public ProductCategory() {
    }

    public ProductCategory(Integer productCategoryId, String name, Date created, Integer createdBy) {
        this.productCategoryId = productCategoryId;
        this.name = name;
        this.created = created;
        this.createdBy = createdBy;
    }

    public Integer getProductCategoryId() {
        return productCategoryId;
    }

    public void setProductCategoryId(Integer productCategoryId) {
        this.productCategoryId = productCategoryId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    public Integer getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(Integer createdBy) {
        this.createdBy = createdBy;
    }
}

ProductServiceImpl.java

ProductServiceImpl.java

@Service
@Transactional
public class ProductServiceImpl implements ProductService {



 @Autowired
     private ProductRepository productRepository;

    public Product findOne(int productId) {
        return productRepository.findOne(productId);
    }

    public List<Product> findAll() {
        List<Product> products = new ArrayList<>();
        productRepository.findAll().forEach(products::add);
        return products;
    }

    @Override
    public List<Product> findBatch(int start, int end) {
        return productRepository.findBatch(start, end);
    }
}

ProductController.java:

ProductController.java:

@RestController
@RequestMapping("/products")
@EnableTransactionManagement
public class ProductController {

    @Autowired
    private ProductService productService;

    @RequestMapping(method = RequestMethod.GET)
    public List<Product> findAll() {
        List<Product> products = productService.findAll();
        return products;
    }

    @RequestMapping(value = "/{productId}", method = RequestMethod.GET)
    public Product findOne(@PathVariable int productId) {
        Product product = productService.findOne(productId);
        return product;
    }

    @RequestMapping(value = "/{start}/{end}", method = RequestMethod.GET)
    public List<Product> findBatch(@PathVariable int start, @PathVariable int end) {
        List<Product> list = productService.findBatch(start, end);
        return list;
    }
}

ApplicationContextConfig.java:

ApplicationContextConfig.java:

public class ApplicationContextConfig {

    @Bean
    public HibernateJpaSessionFactoryBean sessionFactory(EntityManagerFactory emf) {
        HibernateJpaSessionFactoryBean factory = new HibernateJpaSessionFactoryBean();
        factory.setEntityManagerFactory(emf);
        return factory;
    }
}

响应还应该包含一个完整的注入 ProductCategory 对象,但它没有.

The response should also contain a full injected ProductCategory object which it does not.

推荐答案

所以最后,解决方案是将其添加到我的 application.properties 文件中:

So finally, the solution was to add this to my application.properties file:

spring.jpa.hibernate.ddl-auto=validate
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

第一行检查列的存在而不改变它们的结构,而第二行更改 Hibernate 验证的默认命名策略并避免在表名中添加下划线.

The first line checks the presence of columns without changing their structure while the second line changes the default naming strategy that Hibernate validates for and avoids adding underscores to the table names.

这篇关于Spring Boot:使用 Spring Data JPA 读取数据返回不正确的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆