4
I request help to implement a method/way to take the value bound to a selectOneRadio (which is an Enum) and assign it to an attribute within a Bean.
After obtaining the value linked to selectOneRadio, I will pass it as a parameter to a method called newPessoa and so instantiate an attribute of type Person located in a class Client.
I am studying and in parallel developing a Java EE application using JSF, Primefaces and JPA. The main focus of learning is the use of Inheritance with JPA (hence the heritage of Java) and also Composition. I have chosen to use the JOINED inheritance strategy because I believe that in this way the tables in the database are more standardised. Therefore, I implemented 4 classes:
Person (abstract) Personal physique (inherits from Person) Personal (inherits from Person) Client (has a Person attribute since it can be either Personal or Personal)
At first I defined in the class Person an attribute type DEOP, which is an Enum composed by FISICA and JURIDICA, where the idea is: to link the values of this Enum to a "p:selectOneRadio" so that depending on the type that is selected (FISICO or JURIDICO) instantiate the Person object as Personal or Personal.
For this, I also implemented a class (using the Design Patterns Creation Factory Method) Personal factoty. This class has the newPessoa method that takes as a parameter a Personal type and depending on the type (FISICA or JURIDICA) a type of person is instantiated.
Below is the image of a class diagram to demonstrate the scenario of the relationship between the cited classes. Below are also the codes referring to the implementation of the classes.
PS: After completing this part of the implementation, I want to develop a way so that once the page is reinderized, the FISICA option is already selected, like this will be the default type of person, and there will also be a form for each type of person, If FISICA is selected, there will be fields of CPF, RG, etc., if it is JURIDICAL, there will be the fields CNPJ, Insc. State, etc., that is, the form will be dynamic.
Thanks in advance.
Person
@Entity
@Table(name = "PESSOAS")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "PESS_TIPO")
public abstract class Pessoa implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "PESS_CODIGO", nullable = false)
private Integer codigo;
@Enumerated(EnumType.STRING)
@Column(name = "PESS_TIPO_DE_PESSOA")
private PessoaType tipoDePessoa;
@Column(name = "PESS_NOME", length = 100, nullable = false)
private String nome;
@Column(name = "PESS_FONE", length = 20, nullable = false)
private String telefone;
@OneToOne(mappedBy = "pessoa")
private Endereco endereco;
@Column(name = "PESS_OBSERVACAO", length = 255, nullable = true)
private String observacao;
@Column(name = "PESS_STATUS", length = 1, nullable = false)
private Boolean status;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "PESS_DATA_CADASTRO", nullable = false)
private Date dataCadastro;
@Version
@Column(name = "PESS_DATA_ALTERACAO", nullable = false)
private Timestamp dataAlteracao;
protected Pessoa() {
}
// Gets e Sets
Pessoa Física
@Entity
@Table(name = "PESSOA_FISICA")
@DiscriminatorValue(value = "PF")
@PrimaryKeyJoinColumn(name = "PESS_CODIGO")
public class PessoaFisica extends Pessoa implements Serializable {
private static final long serialVersionUID = 1L;
@Column(name = "PESF_CPF", length = 14, nullable = false)
private String cpf;
@Column(name = "PESF_RG", length = 14, nullable = false)
private String rg;
@Column(name = "PESF_ORGAO_EMISSOR_RG", length = 20, nullable = false)
private String orgaoEmissorRg;
@Column(name = "PESF_EMAIL", length = 65, nullable = true)
private String email;
@Column(name = "PESF_CELULAR", length = 14, nullable = true)
private String celular;
@Lob
@Column(name = "PESF_FOTO", nullable = true)
private byte[] foto;
@Temporal(TemporalType.DATE)
@Column(name = "PESF_DATA_NASCIMENTO", nullable = false)
private Date dataNascimento;
@Enumerated(EnumType.STRING)
@Column(name = "PESF_SEXO", nullable = false)
private SexoType sexo;
@OneToMany(mappedBy = "cliente")
private List<PedidoVenda> pedidos;
public PessoaFisica() {
}
Juridical Person
@Entity
@Table(name = "PESSOA_JURIDICA")
@DiscriminatorValue(value = "PJ")
@PrimaryKeyJoinColumn(name = "PESS_CODIGO")
public class PessoaJuridica extends Pessoa implements Serializable {
private static final long serialVersionUID = 1L;
@Column(name = "PESJ_NOME_FANTASIA", length = 100, nullable = false)
private String nomeFantasia;
@Column(name = "PESJ_CNPJ", length = 14, nullable = false)
private String cnpj;
@Column(name = "PESJ_INSCRICAO_ESTADUAL", length = 15, nullable = false)
private String inscricaoEstadual;
@Temporal(TemporalType.DATE)
@Column(name = "PESJ_VALIDADE_INSCRICAO_ESTADUAL", nullable = false)
private Date validadeInscricaoEstadual;
@Column(name = "PESJ_INSCRICAO_MUNICIPAL", length = 15, nullable = true)
private String inscricaoMunicipal;
@Column(name = "PESJ_HOME_PAGE", length = 100, nullable = true)
private String homePage;
@Column(name = "PESJ_FAX", length = 15, nullable = true)
private String fax;
public PessoaJuridica() {
}
Factory class to instantiate a person according to the type passed by parameter.
public class PessoaFactory {
public static Pessoa newPessoa(PessoaType tipo) {
if (tipo == PessoaType.FISICA) {
return new PessoaFisica();
} else if (tipo == PessoaType.JURIDICA) {
return new PessoaJuridica();
} else {
return null;
}
}
}
Bean
@Named(value = "clienteBean")
@SessionScoped
public class ClienteBean extends Bean {
private static final long serialVersionUID = 1L;
@Inject
private ClienteService clienteService;
private Cliente cliente;
private Pessoa pessoa;
private Cliente clienteSelecionado;
private List<Cliente> clientes;
public void instanciarPessoa(ValueChangeEvent event) {
HtmlSelectOneRadio radio = (HtmlSelectOneRadio) event.getComponent();
PessoaType tipo = (PessoaType) radio.getValue();
System.out.println(tipo);
}
public List<PessoaType> getTiposDePessoa() {
return Arrays.asList(PessoaType.values());
}
public List<Cliente> getClientes() {
try {
if (clientes == null) {
clientes = clienteService.listarTodosClientes();
}
return clientes;
} catch (Exception e) {
handleException(e);
return null;
}
}
public String novoCliente() {
cliente = new Cliente();
return redirect(Outcome.CADASTRO_CLIENTE);
}
}
Part of the XHTML file
<h:panelGrid columns="3">
<h:outputLabel value="Tipo de Pessoa" for="tipoPessoa" />
<p:selectOneRadio
id="tipoPessoa"
value="#{clienteBean.pessoa.tipoDePessoa}"
valueChangeListener="#{clienteBean.instanciarPessoa}">
<f:selectItems
value="#{clienteBean.tiposDePessoa}"
var="tipoDePessoa"
itemValue="tipoDePessoa"
itemLabel="#{tipoDePessoa.descricao}">
</f:selectItems>
</p:selectOneRadio>
</h:panelGrid>
Hi @Luiz the implementation suggestions you reported are very similar to the ones I had already created, except for the implementation of the Personal Factory class, because I created something simpler (due to lack of knowledge). I could not understand the last part of your answer regarding the classes responsible for creating the object and then take this object created in the Client class to finish the registration. Could you help me a little more? The difficulty is in taking the selected value in selectOneRadio and moving to the Personal classfactory, I think I should use a Valuechangeevent.
– Clarence
You can use the event to decide which fields should be filled in, in a single form. If the person marks Physics there you can enable the fields CPF and RG and leave Hidden the Legal fields. Then you would have only one Backbean to control this Person and Typodeperson record.. .
– Luiz
In your table Client would have a column of id_person for you to reference. And in the table Pessoa is already referencing the type by @Column(name = "PESS_TIPO_DE_PESSOA"). By the standard of the Factory Method you would have to have an object creation class for each type, I find it a little complicated, but it is quite interesting in case you have the possibility to add more types of people in your system, in addition to Legal and Physical, if never changed, then it would not be necessary.
– Luiz
That’s right @Luiz, in my Client class there is a Pessoa attribute (@Joincolumn(name = "PESS_CODIGO", nullable = false)) In the Personal classfactory the newPessoa method looks like this: 'public class Pessoafactory { public Static Pessoa newPessoa(Personal type) { if (type == Personal type.FISICA) { Return new Personal(); } Else if (type == Persontype.JURIDICA) { Return new Personjuridical(); } Else { Return null; } } }
– Clarence
What I had tried to implement in my Bean to get the selected value in selectOneRadio was a method like this: (sorry, I couldn’t put the formatted code) public void instancePessoa(Valuechangeevent Event) { htmlselectoneradio radio = (Htmlselectoneradio) Event.getComponent(); Personal type = (Personal type) radio.getValue(); System.out.println(type); } but it is not working to get the value, would know to inform me which class to use @Luiz, besides Htmlselectoneradio?
– Clarence