2015-04-10 30 views
27

Mam 3 modele User, House, UserHouseMap. I potrzebuję uzyskać dostęp do domu użytkownika za pośrednictwem mapy. Jedyny problem to stary DB & Nie mogę zmienić faktu, że muszę mapować User na UserHouseMap przy użyciu user.name, który jest kluczem innym niż podstawowy.Jak dołączyć tabele do klucza innego niż podstawowy przy użyciu JPA i Hibernate

Hibernate trzyma daje mi błędy mówiąc muszę mieć go jako klucz podstawowy lub pojawiają się błędy mówiąc A JPA error occurred (Unable to build EntityManagerFactory): Unable to find column with logical name: name in org.hibernate.mapping.Table(users) and its related supertables and secondary tables

Próbowałem @Formula jako obejście, ale to nie działał. Próbowałem też @JoinColumnOrFormula, ale to też nie działało. Oto moje rozwiązanie z @Formula

@Expose 
@ManyToOne(targetEntity = House.class) 
@Formula("(select * from houses inner join user_house_map on houses.house_name = user_house_map.house_name where user_house_map.user_name=name)") 
public House house; 

tutaj był mój próba rozwiązania @JoinColumnOrFormula.

@Expose 
@ManyToOne(targetEntity = House.class) 
@JoinColumnsOrFormulas({ 
     @JoinColumnOrFormula([email protected](value="select name from users where users.id= id", referencedColumnName="name")), 
     @JoinColumnOrFormula(column = @JoinColumn(name= "house_name", referencedColumnName="house_name")) 
}) 
public House house; 

Oto mój mapowanie

@Id 
@GeneratedValue 
@Expose 
public Long id; 

@Expose 
@Required 
@ManyToOne 
@JoinTable(
     name="user_house_map", 
     joinColumns= 
     @JoinColumn(unique=true,name="user_name", referencedColumnName="name"), 
     inverseJoinColumns= 
     @JoinColumn(name="house_name", referencedColumnName="house_name")) 
private House house; 

Oto schematy DB

Użytkownicy

       Table "public.users" 
     Column   |   Type    |   Modifiers   
-----------------------+-----------------------------+----------------------------- 
name     | character varying(255)  | 
id     | integer      | not null 
Indexes: 
    "user_pkey" PRIMARY KEY, btree (id) 
Foreign-key constraints: 
    "housing_fkey" FOREIGN KEY (name) REFERENCES user_house_map(user_name) DEFERRABLE INITIALLY DEFERRED 

Domy

   Table "public.houses" 
    Column  |   Type   | Modifiers 
---------------+------------------------+----------- 
house_name | character varying(255) | not null 
address  | text     | 
city   | text     | 
state   | text     | 
zip   | integer    | 
zip_ext  | integer    | 
phone   | text     | 
Indexes: 
    "house_pkey" PRIMARY KEY, btree (house_name) 
Referenced by: 
    TABLE "user_house_map" CONSTRAINT "house_map_fkey" FOREIGN KEY (house_name) REFERENCES house(house_name) DEFERRABLE INITIALLY DEFERRED 

UserHouseMap

  Table "public.user_house_map" 
    Column |   Type   | Modifiers 
-------------+------------------------+----------- 
user_name | character varying(255) | not null 
house_name | character varying(255) | not null 
Indexes: 
    "user_house_map_pkey" PRIMARY KEY, btree (user_name) 
    "user_house_map_house_key" btree (house_name) 
Foreign-key constraints: 
    "user_house_map_house_fkey" FOREIGN KEY (house_name) REFERENCES houses(house_name) DEFERRABLE INITIALLY DEFERRED 
Referenced by: 
    TABLE "users" CONSTRAINT "housing_fkey" FOREIGN KEY (name) REFERENCES user_house_map(user_name) DEFERRABLE INITIALLY DEFERRED 

Odpowiedz

25

To w jaki sposób odwzorowania powinna wyglądać następująco:

@Entity 
public class User { 

    @Id 
    private Long id; 

    private String name; 

    @OneToMany(mappedBy = "user") 
    private List<UserHouseMap> houses = new ArrayList<>(); 
} 

@Entity 
public class House { 

    @Id 
    @Column(name = "house_name", nullable = false, unique = true) 
    private String house_name; 

    private String address; 

    @OneToMany(mappedBy = "house") 
    private List<UserHouseMap> users = new ArrayList<>(); 
} 

@Entity 
public class UserHouseMap implements Serializable { 

    @Id @ManyToOne 
    @JoinColumn(name = "user_name", referencedColumnName = "name") 
    private User user; 

    @Id @ManyToOne 
    @JoinColumn(name = "house_name", referencedColumnName = "house_name") 
    private House house; 
} 

Zarówno User i House mieć dostęp do swoich związanych UserHouseMap podmiotów, dopasowanie schematu bazy danych.

Korzystanie z two one-to-many associations jest zawsze lepsze niż poleganie na relacjach wiele do wielu.

+0

Wiem, że jest stary, ale miałem czas hellva z tym samym błędem. Twoje rozwiązanie działa, jednak musiałem wprowadzić niewielką zmianę, ale musiałem dodać @Column (name = "name", nullable = false) private String name; Gdybym musiał zgadywać, dlaczego, moja nazwa zmiennej/właściwości nie jest taka sama jak nazwa kolumny jako tabela bazy danych. Tylko FYI dla każdego, kto ma takie same/podobne problemy. –

+0

Dzięki. Dodałem zarówno 'nullable = false' oraz' unique = true', które muszą być wymuszone przez dowolną kolumnę identyfikatora. –

+0

To nie zadziała, jeśli nazwa_użytkownika i nazwa_domu są kluczami innymi niż podstawowe! – Archi

Powiązane problemy