2014-06-12 131 views
0

我正面临单向onetomany映射的一些问题。 我表用户和Rubrica:单向OneToMany映射问题

User (
scode double precision NOT NULL, 
... 
CONSTRAINT utenti_pkey PRIMARY KEY (scode) 
) 

Rubrica (
id serial NOT NULL, 
id_owner integer NOT NULL, 
id_contact integer NOT NULL, 
CONSTRAINT rubrica_pkey PRIMARY KEY (id), 
CONSTRAINT rubrica_fk01 FOREIGN KEY (id_owner) 
    REFERENCES users (scode) MATCH SIMPLE 
    ON UPDATE NO ACTION ON DELETE NO ACTION, 
CONSTRAINT rubrica_fk02 FOREIGN KEY (id_contact) 
    REFERENCES users (scode) MATCH SIMPLE 
    ON UPDATE NO ACTION ON DELETE NO ACTION 
) 

不要介意用户双PKEY。这是客户的表格,我无法修改它。 Rubrica店主,用户和联系人之间的关系,也是一组用户。 用户映射如下:

@SuppressWarnings("serial") 
@Entity 
@Table(name = "utenti", schema = "public") 
public class User implements Serializable { 
    @Id 
    @Column(name = "scode", unique = true, nullable = false) 
    private Integer scode; 
... 
} 

好的。这是问题出现的时间。如果我映射Rubrica这样的:

public class Rubrica2 implements Serializable { 
    @Id 
    @Column(name = "id", nullable = false, unique = true) 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Integer id; 

    @OneToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "id_owner", nullable = false, unique = true, referencedColumnName = "scode") 
    private User owner; 

    @OneToMany(fetch = FetchType.EAGER) 
    @JoinColumn(name = "id_contact", nullable = false, updatable = false, insertable = true, referencedColumnName = "scode") 
    private Set<User> relations = new HashSet<User>(); 
    ... 
} 

JBoss的给了我这个例外在部署:

Caused by: org.hibernate.MappingException: Unable to find column with logical name: scode in org.hibernate.mapping.Table(public.rubrica) and its related 

supertables和辅助表

如果我映射Rubrica这样:

public class Rubrica2 implements Serializable { 
    @Id 
    @Column(name = "id", nullable = false, unique = true) 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Integer id; 

    @OneToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "id_owner", nullable = false, unique = true, referencedColumnName = "scode") 
    private User owner; 

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "scode") 
    private Set<User> relations = new HashSet<User>(); 
    ... 
} 

我在运行时得到了不好的行为。如果我运行此代码

r = new Rubrica2(); 
q2.setParameter("id", ownerID); 
User owner = (User) q2.getSingleResult(); 
r.setOwner(owner); 
q2.setParameter("id", contactID); 
User u = (User) q2.getSingleResult(); 
r.getRelations().add(u); 
entityManager.persist(r); 

我得到这个异常:

Hibernate: insert into public.rubrica (id_owner) values (?) 
11:08:19,440 DEBUG [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (EJB default - 7) 
    ERROR: null values in column "id_contact" violates not-null constraint [n/a]: org.postgresql.util.PSQLException: 
    ERROR: null values in column "id_contact" violates not-null constraint 

我按照理论指出here约一对多单向的。 我使用JPA2.0,Hibernate4(由JBoss7.1.1.Final提供)和PostgresSQL。

+0

是类名Utente是用户? – Gayathri

+0

@Gayathri是的。更新谢谢。 – Francesco

回答

0

这种映射或数据库设计没有意义。如果您希望一个Rubrica拥有多个联系人,那么您不能在rubrica表中具有该关系的外键。一个外键只能引用一个联系,不多。

要映射这样的一对多关联,您需要用户使用rubrica的外键(具有相同rubrica_id的所有用户将成为此rubrica的联系人)或两个表之间的连接表。

+0

帮我理解。你为什么说“没有道理......外键只能引用一个联系人,而不是很多”?用户不会介意是否在Rubrica条目中提及。 Rubrica.id_contact指User.scode,Rubrica中的一行仅指用户作为联系人。怎么了?我认为这个案例与我发布的链接中的Employee - Phone示例非常相似,不是吗? – Francesco

+0

您希望每个rubrica都有*几个*联系人。您尝试使用rubrica表中的用户标识来映射它。因此,代表Rubrica的一个实例的rubrica表的每一行都会引用* one *联系人。你怎么可以参考*使用*一个*用户ID的几个*用户? –

+0

好的。所以整个东西将无法工作,因为实体Rubrica不能同时封装Set并拥有前卫关键。在Employee-Phone示例中,Phone有一个未映射到其实体的Employee的外键。我无法更改用户表,我必须使用连接表。我收到了吗? – Francesco