I have a JPA Mapping question to do.
We have a One-To-Many relationship between two entities (Sale and Pig). Classes follow at the final of this message to ilustrate.
'Sale' is a event on a 'Pig', like many others in the system ('Inspection' is another example). However, 'Sale' is the only event who has One-To-Many relationship with 'Pig', the others has One-to-One.
So, to map all events of a 'Pig' we use a 'PigEvent' entity. We save(insert) a 'PigEvent' object at the same time the user inserts a 'Pig' in the system.
We want to use this entity ('PigEvent') like the 'jointable' of Sale.getPigs() mapping. But doing that, some problem occurs: - when a new 'Sale' is inserted, hibernate try to insert new 'PigEvent' for every 'Pig' in the 'Sale' (this generates a duplicate PK exception, because PigEvent already exists) - when a new 'Sale' is deleted, hibernate deletes 'PigEvent' for every 'Pig' in the 'Sale' (doing this we loose the others Events relationship data)
We understand that this is the normal behaviour of this kind of mapping (One-to-Many with jointable). We want to know how configurate JPA/Hibernate to just load Sale.getPigs() (in SELECT´s), but in INSERT, UPDATE, DELETE operations in 'Sale' don´t action at all in that mapping (Sale.pigs()).
We use Hibernate 3.6.2.
Thanks in advance.
@Entity
public class Pig extends P开发者_JAVA百科ersistente implements Serializable {}
@Entity
public class PigEvent extends Persistente {
@OneToOne
@JoinColumn(name="idpig")
private Pig pig;
@OneToOne
@JoinColumn(name="idapproval")
private Inspection approval
@OneToOne
@JoinColumn(name="idsale")
private Sale sale;
}
@Entity
public class Inspection extends Persistente{
@OneToOne
@JoinColumn(name="idSuino")
private Pig pig;
}
@Entity
public class Sale extends Persistente{
@MOneToMany
@JoinTable(name="e33PigEvent",uniqueConstraints=@UniqueConstraint(columnNames="idpig"),
joinColumns={@JoinColumn(name="idsale",insertable=false,updatable=false)},
inverseJoinColumns={@JoinColumn(name="idpig",insertable=false,updatable=false)})
public Set<Pig> getPigs() {}
}
Table Structure:
CREATE TABLE `e33Pig` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
)
CREATE TABLE `e33PigEvent` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`idPig` int(11) NOT NULL,
`idInspection` int(11) DEFAULT NULL,
`idSale` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idPig` (`idPig`),
CONSTRAINT `fk_e33eventossuino_e33aprovacao1` FOREIGN KEY (`idInspection`) REFERENCES `e33Inspection` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `fk_e33eventossuino_e33suino1` FOREIGN KEY (`idPig`) REFERENCES `e33Pig` (`id`),
CONSTRAINT `fk_e33eventossuino_e33venda1` FOREIGN KEY (`idSale`) REFERENCES `e33Sale` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
);
CREATE TABLE `e33Sale` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
);
CREATE TABLE e33Inspection (
`id` int(11) NOT NULL AUTO_INCREMENT,
`idsuino` int(11) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_e33Inspection_e33suino1` FOREIGN KEY (`idPig`) REFERENCES `e33Pig` (`id`)
) ;
You can't use the same table (e33PigEvent
) to map an entity (PigEvent
) and an association (the OneToMany association). If the table is mapped to an entity, then you don't have a OneToMany association between Sale and Pig anymore: you have a OneToMany between Sale
and PigEvent
, mapped by a foreign key in e33PigEvent
, and a OneToOne
between PigEvent
and Pig
, also mapped by a foreign key in e33PigEvent
.
If you map a OneToMany using a JoinTable, then Hibernate handles insertions and deletions in this table itself, each time you add or remove Pigs from the collection. Since you have additional columns in the join table, you need to create PigEvent instances yourself, and add these instances to the collection of events of the sale.
精彩评论