I am new to Spring, to JPA, JPA Repository concepts, etc. I invented the following exercise;
The rule is as follows: A user through a contest can win only one car, but cars can be won by many users (for example, the user Juan won a Toyota, the user Maria won a Ford, but the user Jaime also won a Toyota, etc etc.).
I have a table "users" and another table called "cars", and in the database there is already data in the table cars.
cars table:
----------------------
| id_car | brand |
----------------------
| 1 | Toyota |
----------------------
| 2 | Ford |
----------------------
| 3 | Honda |
----------------------
users table structure:
---------------------------
| id_user | name | id_car |
---------------------------
The entities would be declared in this way in Java code;
Car:
@Entity
@Table(name="cars")
public class Car {
@Id
@Getter
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column("id_car")
private int idAuto;
@Getter
@Setter
private String brand;
}
User:
@Entity
@Table(name="users")
public class User {
@Id
@Getter
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column("id_user")
private int idUser;
@Getter
@Setter
private String name;
// private int idCar; ???
}
How can I link the user with the car?
If I declare OneToOne
, JoinColumn(name="id_car")
to a property that returns and assigns an object of type Car in the user entity, that is:
@Getter
@Setter
private Car car;
How can I tell the repository or the Entity that I only want to join a new user to a car that already exists in the DB, because to declare this property that I mentioned before, I must assign it an Object of type Car.
user.setCar(new car("Toyota"));
Or:
Car car = repositoryFindById(2);
user.setCar(car);
I don't want to join a new Car, since the car with id 1 already exists, I just want to join it, I don't want to create two transactions (findById
and save
), how can I do something like this:
user.setCar(1); // pass only the car id.
Is there any way to achieve this? or What is the correct way to do it?
CodePudding user response:
I believe you can use @Query annotation and write a native query, we use hibernate JPA at work and also have join tables, but if you are looking for specific information from the data that can join through the mappings, you would need a native custom query.
Also, you don't need the CRUD repository interface, it useful when the query is simple but the more specific you want to get with the data the more you would need to write your own SQL or use Hibernate Query Language.
So a few ways you could go:
Use the @Query annotation and write your own native query
@Query(value = "SELECT * FROM table WHERE column like %info% ", nativeQuery = true) List<AnEntity> getEntity(@Param("info") String info);
Inject an EntityManager and use the createNativeQuery method
There is the hibernate criteria api, where you can basically wrap java around sql with somewhat hard to understand methods for a custom query.
CodePudding user response:
You can get a reference to a car without hitting database like this
Car car = entityManager.getReference(Car.class, 1);
user.setCar(car);
If there is no associated Car with id=1 in the DB an exception will be thrown when you persist user