Domanda

Sto usando Spring with Hibernate come provider JPA e sto cercando di ottenere un @OneToMany (un contatto con molti numeri di telefono) per salvare la chiave esterna nella tabella dei numeri di telefono. Dal mio modulo ottengo un oggetto contatto che contiene un elenco di telefono (numeri). Il contatto viene persistito correttamente (Hibernate recupera un PK dalla sequenza specificata). L'elenco di Telefono (numeri) viene anche persistito con un PK corretto, ma non c'è FK nella tabella Contatti.

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;
    }
}

Spero di aver ottenuto tutti i bit pertinenti sopra, altrimenti per favore fatemi sapere.

È stato utile?

Soluzione

Devi gestire tu stesso le relazioni Java. Per questo genere di cose hai bisogno di qualcosa del tipo:

@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;

  ...
}

Altri suggerimenti

In risposta alla risposta di Cletus. Direi che è importante avere l'annotazione @column sui campi ID, così come tutta la sequenza. Un'alternativa all'uso del parametro mappedBy dell'annotazione @OneToMany è l'uso dell'annotazione @JoinColumn .

A parte ciò, l'implementazione di addPhone deve essere esaminata. Probabilmente dovrebbe essere qualcosa del genere.

public void addPhone(PhoneNumber phone) {
    if (phone == null) {
        return;
    } else {
        if (phoneNumbers == null) {
            phoneNumbers = new ArrayList<Phone>();
        }
        phoneNumbers.add(phone);
        phone.setContact(this);
    }
}

Se la relazione Contact-Phone è unidirezionale, puoi anche sostituire mappedBy nell'annotazione @OneToMany con @JoinColumn (name = " contact_id ") .

@Entity
public class Contact {
  @Id
  private Long id;

  @OneToMany(cascade = CascadeType.PERSIST)
  @JoinColumn(name = "contact_id")
  private List<Phone> phoneNumbers;

  // normal getter/setter
  ...
}

@Entity
public class PhoneNumber {
  @Id
  private Long id;

  ...
}

Simile in JPA @OneToMany - > Riferimento padre - figlio (chiave esterna)

Non credo che il metodo addPhone sia necessario, devi solo impostare il contatto nell'oggetto telefono:

phone.setContact(contact);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top