0

I´m making the model classes using Hibernate, but I don´t know what to do with this kind of relationship.

I have three tables.

Adrress, employee and person.

One emplooye can have one adrress and one person can have one addrress.

I don´t know how map.

Because I thought to use embedded annotattion but doesn´t work.

First is to map my class, I need to put this two entities in address class?

What kind of annotattion i need to use?

I use a superclass with id property and every class extends.

I´m using mysql

my person class

@Entity
@Table(name = "destinatario")
public class Destinatario extends Persistent {

        private static final long serialVersionUID = -7091318100871934315L;

        @ManyToOne(cascade = CascadeType.PERSIST)
        @JoinColumn(name = "endereco_id", referencedColumnName = "id")
        private Endereco endereco;

        @NotNull
        @Size(max = 60)
        @Column(name = "razao_social")
        private String razaoSocial;

        @NotNull
        @Size(max = 14)
        @Column(name = "inscricao_estadual")
        private String inscricaoEstadual;

        @Size(max = 9)
        @Column(name = "inscricao_suframa")
        private String inscricaoSuframa;

        @Size(max = 60)
        @Column(name = "email")
        private String email;

        @Size(max = 14)
        @Column(name = "cnpj")
        private String cnpj;

        @Size(max = 11)
        @Column(name = "cpf")
        private String cpf;

        @OneToMany
        @JoinColumn(name = "destinatario_id")
        private List<NotaFiscal> notaFiscais;
}

my address class

@Entity
@Table(name = "endereco")
public class Endereco extends Persistent {

        private static final long serialVersionUID = -3308931308130690090L;

        public enum UF {

                AC("AC", "Acre"),
                AL("AL", "Alagoas"),
                AP("AP", "Amapá"),
                AM("AM", "Amazonas"),
                BA("BA", "Bahia"),
                CE("CE", "Ceara"),
                DF("DF", "Distrito Federal"),
                ES("ES", "Espirito Santo"),
                GO("GO", "Goiás"),
                MA("MA", "Maranhão"),
                MT("MT", "Mato Grosso"),
                MS("MS", "Mato Grosso do Sul"),
                MG("MG", "Minas Gerais"),
                PA("PA", "Pará"),
                PB("PB", "Paraíba"),
                PR("PR", "Paraná"),
                PE("PE", "Pernambuco"),
                PI("PI", "Piauí"),
                RJ("RJ", "Rio de Janeiro"),
                RN("RN", "Rio Grande do Norte"),
                RS("RS", "Rio Grande do Sul"),
                RO("RO", "Rondônia"),
                RR("RR", "Roraima"),
                SC("SC", "Santa Catarina"),
                SP("SP", "São Paulo"),
                SE("SE", "Sergipe"),
                TO("TO", "Tocantins");

                private final String index;
                private String descricao;

                private UF(String index, String descricao) {
                        this.index = index;
                        this.descricao = descricao;
                }

                public String getNomeEstado() {
                        return descricao;
                }

                public String getIndex() {
                        return index;
                }

        }

        @NotNull
        @Size(max = 60)
        @Column(name = "logradouro", unique = true)
        private String logradouro;

        @NotNull
        @Size(max = 60)
        @Column(name = "numero", unique = true)
        private String numero;

        @Size(max = 60)
        @Column(name = "complemento")
        private String complemento;

        @NotNull
        @Size(max = 60)
        @Column(name = "bairro", unique = true)
        private String bairro;

        @NotNull
        @Size(max = 60)
        @Column(name = "municipio", unique = true)
        private String municipio;

        @Enumerated(EnumType.STRING)
        @NotNull
        //@Type(type = UFType.TYPE)
        @Column(name = "uf", columnDefinition = "varchar", length = 2)
        private UF uf;

        @NotNull
        @Size(max = 8)
        @Column(name = "cep", unique = true)
        private String cep;

        @Size(max = 14)
        @Column(name = "telefone")
        private String telefone;
}

my methods to run and create a person by xml source

public static void main(String[] args) {

        new Processadora().extrairDadosXml("diego");

        ArquivoNotaFiscal arquivoNotaFiscal = null;
        Destinatario destinatario = null;
        NotaFiscal notaFiscal = null;

        destinatario = createDestinatario();
        arquivoNotaFiscal = createArquivoNotaFiscal();
        notaFiscal = createNotaFiscal(arquivoNotaFiscal, emitente, destinatario);

        destinatario.setNotaFiscais(Arrays.asList(notaFiscal));

        DestinatarioDAO<Destinatario> destinatarioDAO = new DestinatarioDAOImpl<>();

        Session session = HibernateSessionFactory.getSession();
        Transaction transaction = session.getTransaction();
        transaction.begin();

        destinatarioDAO.save(destinatario);

        transaction.commit();
}

private static Destinatario createDestinatario() {

        Destinatario destinatario = new Destinatario();

        Endereco endereco = new Endereco();

        endereco.setLogradouro(nFeProc.getNfe().getInfNFe().getDestinatario().getEndereco().getLogradouro());
        endereco.setNumero(nFeProc.getNfe().getInfNFe().getDestinatario().getEndereco().getNumero());
        endereco.setBairro(nFeProc.getNfe().getInfNFe().getDestinatario().getEndereco().getBairro());
        endereco.setComplemento(nFeProc.getNfe().getInfNFe().getDestinatario().getEndereco().getComplemento());
        endereco.setCep(nFeProc.getNfe().getInfNFe().getDestinatario().getEndereco().getCep());
        endereco.setMunicipio(nFeProc.getNfe().getInfNFe().getDestinatario().getEndereco().getMunicipio());
        endereco.setUf(UF.valueOf(nFeProc.getNfe().getInfNFe().getDestinatario().getEndereco().getUF()));
        endereco.setTelefone(nFeProc.getNfe().getInfNFe().getDestinatario().getEndereco().getTelefone());

        destinatario.setEndereco(endereco);

        destinatario.setRazaoSocial(nFeProc.getNfe().getInfNFe().getDestinatario().getRazaoSocial());
        destinatario.setInscricaoEstadual(nFeProc.getNfe().getInfNFe().getDestinatario().getInscricaoEstadual());
        destinatario.setInscricaoSuframa(nFeProc.getNfe().getInfNFe().getDestinatario().getInscricaoSuframa());
        destinatario.setEmail(nFeProc.getNfe().getInfNFe().getDestinatario().getEmail());
        destinatario.setCnpj(nFeProc.getNfe().getInfNFe().getDestinatario().getCnpj());
        destinatario.setCpf(nFeProc.getNfe().getInfNFe().getDestinatario().getCpf());

        return destinatario;

}

my database have foreign key constraint, I´m using mysql

Diego Macario
  • 1,240
  • 2
  • 21
  • 33
  • It all depends on the way tables are linked together. Do you have foreign keys inside address, or inside employee and person? – JB Nizet Nov 03 '13 at 12:51
  • You could read some previous articles to get more ideas: [article1](http://stackoverflow.com/questions/38057/why-onetomany-does-not-work-with-inheritance-in-hibernate) [article2](http://stackoverflow.com/questions/14134695/bi-directional-one-to-many-with-inheritance-not-working-jpa-with-hibernate-3-5). See also the hibernate document [here](http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/inheritance.html) – Paul Lo Nov 03 '13 at 14:20
  • I have foreign key in table person and employee – Diego Macario Nov 03 '13 at 14:22
  • OK, so you have three entities. And you have a OneToOne from Person to Address, using a JoinColumn. And a similar OneToOne from Employee to Address, also using a JoinColumn. Read the hibernate documentation, try to code something and come back if it doesn't work, with your code. – JB Nizet Nov 03 '13 at 14:44
  • First of, thanks for your support, asking a friend, he told me to study about the unidirecional and bidericional relationship, and "N" peoples or employes can have the same address so it is oneToMany – Diego Macario Nov 03 '13 at 15:29
  • Then you need a ManyToOne from person to address (and employee to address), instead of a OneToOne. Still using a JoinColumn. – JB Nizet Nov 03 '13 at 16:06
  • Yes, I´ve already put, but I confused how to indetify if my relationship is bidirectional and unidirectional. I´m reading something found in google, but I don´t know if I doing the rigth thing. – Diego Macario Nov 03 '13 at 16:52
  • 1
    You don't have to *identify* if an association is unidirectional or bidirectional. That's an implementation **choice** that **you** must do. You can map the association as a unidirectional ManyToOne from Person to Address, or as a unidirectional OneToMany from Address to person, or as a bidirectional OneToMany/ManyToOne. It's completely up to you. In that case, I would probably choose the unidirectional ManyToOne option. – JB Nizet Nov 03 '13 at 17:27
  • Thanks for your advice, but I have other relationship in my project, and I looking for tips to choose the best implementation. Do you suggest any read? Because most of sites shows that direction of dates when using uni or bi. – Diego Macario Nov 03 '13 at 17:35
  • For example, other relationship is...One person can have "N" invoices, but one invoice belong to one person. It´s my dificult to imagine how to use. – Diego Macario Nov 03 '13 at 17:47
  • It depends on your use cases, the queries you need to make, etc. For example, there's a good chance that your app displays a person, with his/her address. So it's useful to get the address from a person. But I doubt that the app has to display an address, with all the persons living at this address. So being able to get the persons from an address is not necessary. If it is, then make the association bidirectional. Don't be afraid of making a simple choice now, and to change it later if you need to. – JB Nizet Nov 03 '13 at 18:26
  • Ok, I´ve tried to execute my code. My class person has this property ` @ManyToOne(cascade = CascadeType.PERSIST) @JoinColumn(name = "address_id", referencedColumnName = "id") private Address address;` But when I run the project, Eclipse shows stacktrace telling this ERROR: Column 'address_id' cannot be null org.hibernate.exception.ConstraintViolationException: could not execute statement – Diego Macario Nov 03 '13 at 18:33
  • The code matters. Show us how your person table is defined, and the code that you're executing, along with the code of the two entities. It seems you're trying to create a person without an address, although address_id is defined as not null in the database. – JB Nizet Nov 03 '13 at 18:37
  • My code is in Portuguese because I´m from Brazil, but i put in pastebin. The first class is the person, the second is the address, the third part is the main method that I got the register from a XML and trying to save into database and the last method is about criate one person with his address. http://pastebin.com/Z4ku6pZC – Diego Macario Nov 03 '13 at 18:49
  • Don't post it in pastebin. Post it here. Click the edit link at the bottom of your question. And while you're at it, post only the relevant parts. – JB Nizet Nov 03 '13 at 18:54

1 Answers1

0

I found my problem, I was saving only one object, because I thought if I use the save for the object who contains other it will save, but I need before save the address and later the person.

So this way everthing worked.

Diego Macario
  • 1,240
  • 2
  • 21
  • 33