Hibernate - @ManyToOne注释创建了其他列

时间:2015-12-01 17:19:02

标签: java mysql hibernate

所以我正在关注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”表中表示,我不打算有这个额外的列已创建。

我做双向映射的方式是错误的吗?在没有创建额外列的情况下,将此方法运行的正确方法是什么?

3 个答案:

答案 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属性中指定关系