I'm using Spring with Hibernate as a JPA provider and are trying to get a @OneToMany (a contact having many phonenumbers) to save the foreign key in the phone numbers table. From my form i get a Contact object that have a list of Phone(numbers) in it. The Contact get persisted properly (Hibernate fetches an PK from the specified sequence). The list of Phone(numbers) also gets persisted with a correct PK, but there's no FK to the Contacts table.
public class Contact implements Serializable { @OneToMany(mappedBy = "contactId", cascade = CascadeType.ALL, fetch=FetchType.EAGER) private List<Phone> phoneList; } public class Phone implements Serializable { @JoinColumn(name = "contact_id", referencedColumnName = "contact_id") @ManyToOne private Contact contactId; } @Repository("contactDao") @Transactional(readOnly = true) public class ContactDaoImpl implements ContactDao { @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) public void save(Contact c) { em.persist(c); em.flush(); } } @Controller public class ContactController { @RequestMapping(value = "/contact/new", method = RequestMethod.POST) public ModelAndView newContact(Contact c) { ModelAndView mv = new ModelAndView("contactForm"); contactDao.save(c); mv.addObject("contact", c); return mv; } }
Hopefully I got all of the relevant bits above, otherwise please let me know.
Implementing With a Foreign Key in JPA. Note that we place the @OneToOne annotation on the related entity field, Address. Also, we need to place the @JoinColumn annotation to configure the name of the column in the users table that maps to the primary key in the address table.
Simply put, one-to-many mapping means that one row in a table is mapped to multiple rows in another table. Let's look at the following entity-relationship diagram to see a one-to-many association: For this example, we'll implement a cart system where we have a table for each cart and another table for each item.
You can have multiple one-to-many associations, as long as only one is EAGER.
Simple Identifiers The most straightforward way to define an identifier is by using the @Id annotation. Simple ids are mapped using @Id to a single property of one of these types: Java primitive and primitive wrapper types, String, Date, BigDecimal and BigInteger.
You have to manage the Java relationships yourself. For this kind of thing you need something like:
@Entity public class Contact { @Id private Long id; @OneToMany(cascade = CascadeType.PERSIST, mappedBy = "contact") private List<Phone> phoneNumbers; public void addPhone(PhoneNumber phone) { if (phone != null) { if (phoneNumbers == null) { phoneNumbers = new ArrayList<Phone>(); } phoneNumbers.add(phone); phone.setContact(this); } } ... } @Entity public class Phone { @Id private Long id; @ManyToOne private Contact contact; ... }
In reply to Cletus' answer. I would say that it's important to have the @column
annotation on the id fields, as well as all the sequence stuff. An alternative to using the mappedBy parameter of the @OneToMany
annotation is to use the @JoinColumn
annotation.
As a kinda aside your implementation of addPhone needs looking at. It should probably be something like.
public void addPhone(PhoneNumber phone) { if (phone == null) { return; } else { if (phoneNumbers == null) { phoneNumbers = new ArrayList<Phone>(); } phoneNumbers.add(phone); phone.setContact(this); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With