简体   繁体   English

无法使用Spring Data JPA创建JOIN

[英]Unable to create a JOIN using Spring Data JPA

I'm new to Spring Data and tried to solve the issue by following this post on SO and some other tutorials but without much success. 我是Spring Data的新手,并试图通过关注SO上的这篇文章和其他一些教程来解决此问题,但没有成功。

I'm trying to make a simple Join using Spring Data JPA between 2 tables. 我试图在2个表之间使用Spring Data JPA做一个简单的Join。 The tables in the database are called: * user_vehicle -> contains information about all vehicles per user since 1 user can have many vehicles * vehicle_model which contains data about vehicle models (id, name, etc) 数据库中的表称为:* user_vehicle->包含有关每个用户的所有车辆的信息,因为1个用户可以拥有许多车辆* vehicle_model包含有关车辆型号的数据(ID,名称等)

Current data in the database in the user_vehicle table: user_vehicle表中数据库中的当前数据:
ID | ID | vehicle_id | vehicle_id | user_id 用户身份
1 | 1 | 1 | 1 | 1 1个
2 | 2 | 2 | 2 | 1 1个

Here is the code I've tried but can't get it to work (getters and setters are removed from the post to shorten it): 这是我尝试过但无法正常工作的代码(从帖子中删除了getter和setter可以缩短代码):

@Entity(name = "vehicle_model")
public class VehicleModel {

@Id
@Min(1)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long manufacturerId;
private String title;
private int ccm;
private int kw;
private int yearOfManufacture;
private int engineTypeId;
private boolean isActive;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "vehicle_id", insertable = false, updatable = false)
@Fetch(FetchMode.JOIN)
private UserVehicle userVehicle;
}


@Entity(name = "user_vehicle")
public class UserVehicle {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(nullable = false)
private long vehicleId;
@Column(nullable = false)
private long userId;

@OneToMany(targetEntity = VehicleModel.class, mappedBy = "userVehicle", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
List<VehicleModel> vehicleModels;
}


@Repository
public interface UserVehicleRepository extends CrudRepository<UserVehicle, Long> 
{
    Iterable<UserVehicle> findVehicleModelsByUserId(Long userId);
}

I'm expecting to get 2 results in the iterable with filled vehicle_model data. 我期望在填充了vehicle_model数据的迭代中获得2个结果。 Instead I get 2 results but for the vehicleModels property I get "Unable to evaluate the expression Method threw 'org.hibernate.exception.SQLGrammarException' exception." 相反,我得到2个结果,但是对于vehicleModels属性,我得到“无法评估表达式Method抛出了'org.hibernate.exception.SQLGrammarException'异常”。

Here is the output from the console: 这是控制台的输出:

2019-06-23 02:04:10.988 DEBUG 5896 --- [nio-8080-exec-1] org.hibernate.SQL : select uservehicl0_.id as id1_1_, uservehicl0_.user_id as user_id2_1_, uservehicl0_.vehicle_id as vehicle_3_1_ from user_vehicle uservehicl0_ where uservehicl0_.user_id=? 2019-06-23 02:04:11.034 DEBUG 5896 --- [nio-8080-exec-1] org.hibernate.SQL : select vehiclemod0_.vehicle_id as vehicle_9_4_0_, vehiclemod0_.id as id1_4_0_, vehiclemod0_.id as id1_4_1_, vehiclemod0_.ccm as ccm2_4_1_, vehiclemod0_.engine_type_id as engine_t3_4_1_, vehiclemod0_.is_active as is_activ4_4_1_, vehiclemod0_.kw as kw5_4_1_, vehiclemod0_.manufacturer_id as manufact6_4_1_, vehiclemod0_.title as title7_4_1_, vehiclemod0_.vehicle_id as vehicle_9_4_1_, vehiclemod0_.year_of_manufacture as year_of_8_4_1_ from vehicle_model vehiclemod0_ where vehiclemod0_.vehicle_id=? 2019-06-23 02:04:11.035 WARN 5896 --- [nio-8080-exec-1] ohengine.jdbc.spi.SqlExceptionHelper : SQL Error: 1054, SQLState: 42S22 2019-06-23 02:04:11.035 ERROR 5896 --- [nio-8080-exec-1] ohengine.jdbc.spi.SqlExceptionHelper : Unknown column 'vehiclemod0_.vehicle_id' in 'field list' 2019-06-23 02:04:11.036 DEBUG 5896 --- [nio-8080-exec-1] org.hibernate.SQL : select vehiclemod0_.vehicle_id as vehicle_9_4_0_, vehiclemod0_.id as id1_4_0_, vehiclemod0_.id as id1_4_1_, vehiclemod0_.ccm as ccm2_4_1_, vehiclemod0_.engine_type_id as engine_t3_4_1_, vehiclemod0_.is_active as is_activ4_4_1_, vehiclemod0_.kw as kw5_4_1_, vehiclemod0_.manufacturer_id as manufact6_4_1_, vehiclemod0_.title as title7_4_1_, vehiclemod0_.vehicle_id as vehicle_9_4_1_, vehiclemod0_.year_of_manufacture as year_of_8_4_1_ from vehicle_model vehiclemod0_ where vehiclemod0_.vehicle_id=? 2019-06-23 02:04:11.037 WARN 5896 --- [nio-8080-exec-1] ohengine.jdbc.spi.SqlExceptionHelper : SQL Error: 1054, SQLState: 42S22 2019-06-23 02:04:11.037 ERROR 5896 --- [nio-8080-exec-1] ohengine.jdbc.spi.SqlExceptionHelper : Unknown column 'vehiclemod0_.vehicle_id' in 'field list' 2019-06-23 02:04:11.038 DEBUG 5896 --- [nio-8080-exec-1] org.hibernate.SQL : select vehiclemod0_.vehicle_id as vehicle_9_4_0_, vehiclemod0_.id as id1_4_0_, vehiclemod0_.id as id1_4_1_, vehiclemod0_.ccm as ccm2_4_1_, vehiclemod0_.engine_type_id as engine_t3_4_1_, vehiclemod0_.is_active as is_activ4_4_1_, vehiclemod0_.kw as kw5_4_1_, vehiclemod0_.manufacturer_id as manufact6_4_1_, vehiclemod0_.title as title7_4_1_, vehiclemod0_.vehicle_id as vehicle_9_4_1_, vehiclemod0_.year_of_manufacture as year_of_8_4_1_ from vehicle_model vehiclemod0_ where vehiclemod0_.vehicle_id=? 2019-06-23 02:04:11.039 WARN 5896 --- [nio-8080-exec-1] ohengine.jdbc.spi.SqlExceptionHelper : SQL Error: 1054, SQLState: 42S22 2019-06-23 02:04:11.040 ERROR 5896 --- [nio-8080-exec-1] ohengine.jdbc.spi.SqlExceptionHelper : Unknown column 'vehiclemod0_.vehicle_id' in 'field list' 2019-06-23 02:04:11.042 DEBUG 5896 --- [nio-8080-exec-1] org.hibernate.SQL : select vehiclemod0_.vehicle_id as vehicle_9_4_0_, vehiclemod0_.id as id1_4_0_, vehiclemod0_.id as id1_4_1_, vehiclemod0_.ccm as ccm2_4_1_, vehiclemod0_.engine_type_id as engine_t3_4_1_, vehiclemod0_.is_active as is_activ4_4_1_, vehiclemod0_.kw as kw5_4_1_, vehiclemod0_.manufacturer_id as manufact6_4_1_, vehiclemod0_.title as title7_4_1_, vehiclemod0_.vehicle_id as vehicle_9_4_1_, vehiclemod0_.year_of_manufacture as year_of_8_4_1_ from vehicle_model vehiclemod0_ where vehiclemod0_.vehicle_id=? 2019-06-23 02:04:11.043 WARN 5896 --- [nio-8080-exec-1] ohengine.jdbc.spi.SqlExceptionHelper : SQL Error: 1054, SQLState: 42S22 2019-06-23 02:04:11.043 ERROR 5896 --- [nio-8080-exec-1] ohengine.jdbc.spi.SqlExceptionHelper : Unknown column 'vehiclemod0_.vehicle_id' in 'field list' 2019-06-23 02:04:11.045 DEBUG 5896 --- [nio-8080-exec-1] org.hibernate.SQL : select vehiclemod0_.vehicle_id as vehicle_9_4_0_, vehiclemod0_.id as id1_4_0_, vehiclemod0_.id as id1_4_1_, vehiclemod0_.ccm as ccm2_4_1_, vehiclemod0_.engine_type_id as engine_t3_4_1_, vehiclemod0_.is_active as is_activ4_4_1_, vehiclemod0_.kw as kw5_4_1_, vehiclemod0_.manufacturer_id as manufact6_4_1_, vehiclemod0_.title as title7_4_1_, vehiclemod0_.vehicle_id as vehicle_9_4_1_, vehiclemod0_.year_of_manufacture as year_of_8_4_1_ from vehicle_model vehiclemod0_ where vehiclemod0_.vehicle_id=? 2019-06-23 02:04:11.046 WARN 5896 --- [nio-8080-exec-1] ohengine.jdbc.spi.SqlExceptionHelper : SQL Error: 1054, SQLState: 42S22 2019-06-23 02:04:11.046 ERROR 5896 --- [nio-8080-exec-1] ohengine.jdbc.spi.SqlExceptionHelper : Unknown column 'vehiclemod0_.vehicle_id' in 'field list' 2019-06-23 02:04:11.048 DEBUG 5896 --- [nio-8080-exec-1] org.hibernate.SQL : select vehiclemod0_.vehicle_id as vehicle_9_4_0_, vehiclemod0_.id as id1_4_0_, vehiclemod0_.id as id1_4_1_, vehiclemod0_.ccm as ccm2_4_1_, vehiclemod0_.engine_type_id as engine_t3_4_1_, vehiclemod0_.is_active as is_activ4_4_1_, vehiclemod0_.kw as kw5_4_1_, vehiclemod0_.manufacturer_id as manufact6_4_1_, vehiclemod0_.title as title7_4_1_, vehiclemod0_.vehicle_id as vehicle_9_4_1_, vehiclemod0_.year_of_manufacture as year_of_8_4_1_ from vehicle_model vehiclemod0_ where vehiclemod0_.vehicle_id=? 2019-06-23 02:04:11.049 WARN 5896 --- [nio-8080-exec-1] ohengine.jdbc.spi.SqlExceptionHelper : SQL Error: 1054, SQLState: 42S22 2019-06-23 02:04:11.049 ERROR 5896 --- [nio-8080-exec-1] ohengine.jdbc.spi.SqlExceptionHelper : Unknown column 'vehiclemod0_.vehicle_id' in 'field list'

Found a solution here: https://www.baeldung.com/jpa-many-to-many 在此处找到解决方案: https : //www.baeldung.com/jpa-many-to-many

I've been looking it a bit wrong since this is a ManyToMany relationship. 我一直认为这有点不对,因为这是一个ManyToMany关系。 My idea was to go to the "middle" table and select all vehicle_id where userId = :id and from the list of vehicle_ids to get details for each vehicle. 我的想法是转到“中间”表,然后从vehicle_ids列表中选择userId =:id的所有vehicle_id,以获取每辆车的详细信息。

Here is the correct implementation that works: 这是有效的正确实现:

@Entity(name = "user")
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String firstName;
private String lastName;
private boolean isActive;

@OneToMany(mappedBy = "user")
private Set<UserVehicle> userVehicles;

@Entity(name = "user_vehicle")
public class UserVehicle {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private boolean isActive;

@ManyToOne
@JoinColumn(name = "vehicle_id")
private Vehicle vehicle;

@ManyToOne
@JoinColumn(name = "user_id")
private User user;


@Entity(name = "vehicle_model")
public class Vehicle {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long manufacturerId;
private String title;
private int ccm;
private int kw;
private int yearOfManufacture;
private int engineTypeId;
private boolean isActive;

@OneToMany(mappedBy = "vehicle")
private Set<UserVehicle> userVehicles;

Finally, in the repository Interface I have a method like this: 最后,在存储库接口中,我有一个像这样的方法:

public interface UserVehicleRepository extends CrudRepository<UserVehicle, Long> {

Iterable<UserVehicle> findVehicleModelsByUserId(Long userId);

The output comes out like this: 输出结果如下:

[
    {
        "id": 2,
        "vehicle": {
            "id": 2,
            "manufacturerId": 1,
            "title": "Fazer FZ1S",
            "ccm": 998,
            "kw": 110,
            "yearOfManufacture": 2008,
            "engineTypeId": 1,
            "active": true
        },
        "user": {
            "id": 2,
            "username": "sfajkovic",
            "password": "33",
            "firstName": "Ivan",
            "lastName": "Fajkovic",
            "active": true
        },
        "active": true
    }
]

The issue is not that I don't really want the user object in the result so now I need to figure that one out. 问题不是我真的不想要结果中的用户对象,所以现在我需要弄清楚那个对象。 And after that, I will try to map VehicleManufacturer class to get those results as well in the same response. 之后,我将尝试映射VehicleManufacturer类以在相同响应中获得这些结果。

Here is the solution to do what I intentionally wanted - to search Vehicles based on the user_id in the user_vehicle table: 这是我想要做的解决方案-根据user_vehicle表中的user_id搜索车辆:

@Entity(name = "user_vehicle")
public class UserVehicle {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;
  private boolean isActive;
  private long userId;

  @ManyToOne
  @JoinColumn(name = "vehicle_id")
  private Vehicle vehicle;


@Entity(name = "vehicle_model")
public class Vehicle {

  @Id
  @Min(1)
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private Long manufacturerId;
  private String title;
  private int ccm;
  private int kw;
  private int yearOfManufacture;
  private int engineTypeId;
  private boolean isActive;

  @OneToMany(mappedBy = "vehicle")
  private Set<UserVehicle> userVehicles;


@Repository
public interface UserVehicleRepository extends CrudRepository<UserVehicle, Long> {

  Iterable<UserVehicle> findVehicleModelsByUserId(Long userId);

The User class is actually not used at all: 实际上根本不使用User类:

@Entity(name = "user")
public class User {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String username;
  private String password;
  private String firstName;
  private String lastName;
  private boolean isActive;

This is a OneToMany relationship now and is doing what I actually wanted in the first time. 现在这是一个一对多的关系,并且是我第一次真正想要的。

Hope it helps someone 希望对别人有帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM