Pergunta

Eu estou usando Spring com Hibernate como provedor JPA e está tentando obter um @OneToMany (um contato ter muitos phonenumbers) para guardar a chave estrangeira na tabela de números de telefone. De minha forma i obter um objeto de contato que tem uma lista de telefone (números) na mesma. O Contato entrar persistiu adequadamente (Hibernate busca um PK a partir da sequência especificada). A lista de telefone (números) também fica persistiu com uma PK correta, mas não há nenhuma FK para a tabela de contatos.

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

Espero que eu tenho todas as partes relevantes acima, caso contrário, por favor me avise.

Foi útil?

Solução

Você tem que gerir as relações Java si mesmo. Para este tipo de coisa que você precisa de algo como:

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

  ...
}

Outras dicas

Em resposta a resposta Cletus'. Eu diria que é importante ter a anotação @column nos campos id, bem como todo o material sequência. Uma alternativa ao uso do parâmetro mappedBy da anotação @OneToMany é usar a anotação @JoinColumn.

Como um meio de lado sua implementação do addPhone precisa olhar. Provavelmente deve ser algo como.

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

Se o relacionamento Contato-Phone é unidirecional, você pode também substituir mappedBy na anotação @OneToMany com @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;

  ...
}

JPA @OneToMany -> Pais - Referência da Criança (chave estrangeira)

Eu não acho que o addPhone método é necessário, você só tem que definir o contato no objeto telefone:

phone.setContact(contact);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top