2015-12-01 2 views
1

Итак, я следую учебнику о спящем режиме, поскольку я хочу использовать фреймворк в предстоящем проекте. У меня возникла проблема с аннотациями @ManyToOne и @OneToMay и двунаправленным отображением. То, что я хочу сделать, - это очень простой материал. Я просто хочу две таблицы, один из которых представляет пользователя, а другой - автомобиль. Теперь я хочу, чтобы пользователь мог иметь много автомобилей, и автомобиль должен «знать» пользователя, которому он принадлежит.Hibernate - примечание @ManyToOne создает дополнительную колонку

Как представляется, «наилучшей практикой» является создание дополнительной таблицы, которая поддерживает соединение между пользователями и транспортными средствами. Я попытался сделать это с помощью аннотации @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", [email protected](name="USER_ID"), 
      [email protected](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   | 
+-------+----------+ 

Как я понимаю, дополнительный столбец «user_userId» который был создан спящим режимом, кажется ненужным, поскольку связь между пользователями и транспортными средствами уже представлена ​​в таблице «USER_VEHICLE», и я не собирался создавать этот дополнительный столбец.

Является ли способ, которым я неправильно использовал двунаправленное отображение? И каков правильный способ заставить это работать без создания дополнительного столбца?

+1

Это присоединиться к таблице ненужно в одном для многих отношениях. Это необходимо только во многих отношениях. Поскольку автомобиль назначается только одному пользователю, ключ foriegn из таблицы пользователя входит в таблицу транспортных средств (дополнительная колонка, которую вы видите). Стол соединения необходим только в том случае, если пользователь может иметь несколько транспортных средств и транспортные средства, которые могут иметь несколько пользователей. –

ответ

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  | 
+---------+  +------------+ +---------+------------+-------------+ 
+0

Спасибо за подробный ответ, очень ценим! Я изменил свой код на то, что вы предложили, и он отлично работает без дополнительной таблицы, которую я создал ранее. – whimper

0

Это нормально, что столбец сгенерирован. Сторона Many в отношении базы данных должна сохранять значение FK.

Попробуйте удалить @Join аннотацию ... Просто @OneToMany

0

Попробуйте указать отношения в Vehicle стороне и в User использования боковой mapedBy собственности

Смежные вопросы