所以我正在关注hibernate的教程,因为我想在即将到来的项目中使用该框架。我遇到了@ManyToOne和@OneToMay注释和双向映射的问题。我想做的是非常基本的东西。我只想要两个表,一个表示用户,另一个表示车辆。现在我希望用户能够拥有许多车辆并且汽车应该“知道”它所属的用户。
因为创建一个包含用户和车辆之间连接的额外表格似乎是“最佳实践”。我尝试使用@JoinTable注释(见下文)来做到这一点,但它不能正常工作。
为此,我编写了以下类:
UserDetails.java
@Entity
@Table(name="USER_DETAILS")
public class UserDetails {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int userId;
private String userName;
private String email;
@OneToMany()
@JoinTable(name="USER_VEHICLE", joinColumns=@JoinColumn(name="USER_ID"),
inverseJoinColumns=@JoinColumn(name="VEHICLE_ID")
)
private Collection<Vehicle> vehicle = new ArrayList<Vehicle>();
...
getters and setters
vehicle.java
@Entity
public class Vehicle {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int vehicleId;
private String vehicleName;
@ManyToOne
private UserDetails user;
...
getters and setters
上课测试以上内容:
HibernateTest.Java
public class HibernateTest {
/**
*
* @param args
*/
public static void main(String[] args){
UserDetails user1 = new UserDetails();
user1.setUserName("testUser1");
user1.setEmail("testEmail1");
Vehicle vehicle1 = new Vehicle();
vehicle1.setVehicleName("Car");
Vehicle vehicle2 = new Vehicle();
vehicle2.setVehicleName("Jeep");
user1.getVehicle().add(vehicle1);
user1.getVehicle().add(vehicle2);
vehicle1.setUser(user1);
vehicle2.setUser(user1);
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(user1);
session.save(vehicle1);
session.save(vehicle2);
session.getTransaction().commit();
session.close();
当我运行它时,它会在没有任何错误或异常的情况下执行,并创建以下表格:
USER_DETAILS
+------+----------+---------+
|userId|email |userName |
+------+----------+---------+
|1 |testEmail1|testUser1|
+------+----------+---------+
VEHICLE
+---------+-----------+-----------+
|vehicleId|vehicleName|user_userId| <- did not expect this column
+---------+-----------+-----------+
|1 |Car |1 |
+---------+-----------+-----------+
|2 |Jeep |1 |
+---------+-----------+-----------+
USER_VEHICLE
+------+----------+
|USER_ID|VEHICLE_ID|
+-------+----------+
|1 |1 |
+-------+----------+
|1 |2 |
+-------+----------+
据我所知,由hibernate创建的附加列“user_userId”似乎是不必要的,因为用户和车辆之间的连接已经在“USER_VEHICLE”表中表示,我不打算有这个额外的列已创建。
我做双向映射的方式是错误的吗?在没有创建额外列的情况下,将此方法运行的正确方法是什么?
答案 0 :(得分:1)
@JoinTable
关系, @ManyToMany
是必要的。
@Entity
public class UserDetails {
/* ... */
@ManyToMany
@JoinTable(name = "user_vehicle",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "vehicle_id"))
private List<Vehicle> vehicles;
}
@Entity
public class Vehicle {
/* ... */
}
USER_DETAILS VEHICLE USER_VEHICLE
+---------+ +------------+ +---------+------------+
| user_id | | vehicle_id | | user_id | vehicle_id |
+---------+ +------------+ +---------+------------+
| 1 | | 1 | | 1 | 1 |
+---------+ +------------+ +---------+------------+
由于您不希望如此,您可以像这样删除@JoinTable
:
@Entity
public class UserDetails {
/* ... */
@OneToMany(mappedBy = "user")
private List<Vehicle> vehicles;
}
@Entity
public class Vehicle {
/* ... */
@ManyToOne
private UserDetails user;
}
USER_DETAILS VEHICLE
+---------+ +------------+---------+
| user_id | | vehicle_id | user_id |
+---------+ +------------+---------+
| 1 | | 1 | 1 |
+---------+ +------------+---------+
如果要为(UserDetails,Vehicle)元组存储其他数据,则只需要第三个表,在这种情况下,您将创建第三个类。
@Entity
public class UserDetails {
/* ... */
@OneToMany(mappedBy = "user")
private List<UserVehicle> vehicles;
}
@Entity
public class Vehicle {
/* ... */
}
@Entity
public class UserVehicle {
/* ... */
@ManyToOne
private UserDetails user;
@ManyToOne
private Vehicle vehicle;
@Basic
private String someString;
}
USER_DETAILS VEHICLE USER_VEHICLE
+---------+ +------------+ +---------+------------+-------------+
| user_id | | vehicle_id | | user_id | vehicle_id | some_string |
+---------+ +------------+ +---------+------------+-------------+
| 1 | | 1 | | 1 | 1 | Hello |
+---------+ +------------+ +---------+------------+-------------+
答案 1 :(得分:0)
生成列是正常的。数据库关系中的Many侧面必须保存FK
值。
尝试删除@Join
注释...只需@OneToMany
答案 2 :(得分:0)
尝试在Vehicle
侧和User
侧使用mapedBy
属性中指定关系