Reputation: 1802
I'm facing some problems with unidirectional onetomany mapping. I got tables Users and Rubrica:
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
)
Don't mind about Users double PKey. It's a customer's table and I can't modify it. Rubrica store relation between its owner, a User, and contacts, a set of User too. User is mapped as follow:
@SuppressWarnings("serial")
@Entity
@Table(name = "utenti", schema = "public")
public class User implements Serializable {
@Id
@Column(name = "scode", unique = true, nullable = false)
private Integer scode;
...
}
Ok. Here is when problems come. If I map Rubrica like this:
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 gave me this exception at deploy:
Caused by: org.hibernate.MappingException: Unable to find column with logical name: scode in org.hibernate.mapping.Table(public.rubrica) and its related
supertables and secondary tables
If I map Rubrica this way:
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>();
...
}
I got bad behavior at runtime. If I run this code
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);
I got this exception:
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
I follow theory indicated here about onetomany unidirectional. I'm using JPA2.0, Hibernate4 (as provided by JBoss7.1.1.Final) and PostgresSQL.
Upvotes: 1
Views: 1380
Reputation: 692191
This mapping, or the database design, makes no sense. If you want one Rubrica to have many contacts, you can't have a foreign key to the relation in the rubrica table. A foreign key can only reference one contact, not many.
To map such a one-to-many association, you would need a foreign key in user to rubrica (all the users having the same rubrica_id would be the contacts of this rubrica), or a join table between both tables.
Upvotes: 1