iReport

8 respostas
RicardoYukito

Tenho um relatorio de Clientes, onde busco pessoas Fisicas e Juridicas,

Fisica e Juridia herdam de Pessoa

e Cliente tem uma ligação com Pessoa através do atributo clientePessoa.

Cliente:

@ManyToOne (targetEntity=Pessoa.class)

    @Cascade (org.hibernate.annotations.CascadeType.EVICT)
    @JoinColumn (name= "CLIENTE_PESSOA")
    @ForeignKey (name = "CLIENTE_PESSOA_FK")
    private Pessoa pessoaCliente;

Fisica tem RG , Juridica CPNJ.

O problema é: se no mesmo relatorio eu coloco um pessoaCliente.getCpf() + pessoaCliente.getCnpj(), da o seguinte erro:

Source text : $F{pessoaCliente}.getCnpj()
Caused by: groovy.lang.MissingMethodException: No signature of method: Model.Fisica.getCnpj() is applicable for argument types: () values: {}

Pois uma pessoa fisica nao possui cnpj, como configurar no ireport essa situação ? se o clientePessoa for Fisica pegue apenas elementos de Fisica ? :S

eu passo a lista de clientes pronta pelo JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(listaDeCliente);

8 Respostas

rdmardegam

Poderia colocar as classes para melhor visualização do problema? Assim como a coleção que é setada no JRBeanCollectionDataSource ?

RicardoYukito
Cliente :
@Entity
@Table (name ="CLIENTE")
@Proxy(lazy=false)
public class Cliente implements Serializable {

    @Id
    @SequenceGenerator (name= "Cliente_seq", sequenceName="cliente_seq", initialValue=1, allocationSize=1)
    @GeneratedValue (strategy=GenerationType.SEQUENCE, generator="Cliente_seq")
    @Column (name= "CLIENTE_ID", nullable=false )
    private int clienteId;

    @Temporal(TemporalType.DATE)
    @Column (name ="DATA_CADASTRO")
    private Date dataCadCli;


    @ManyToOne (targetEntity=Pessoa.class)

    @Cascade (org.hibernate.annotations.CascadeType.EVICT)
    @JoinColumn (name= "CLIENTE_PESSOA")
    @ForeignKey (name = "CLIENTE_PESSOA_FK")
    private Pessoa pessoaCliente;

   @OneToMany (mappedBy="cliente", fetch=FetchType.LAZY)   
   @IndexColumn (name= "CLIENTE_INDEX")
   private Collection<Compromisso> compromisso =  new ArrayList<Compromisso>();

Pessoa

@Entity
@Table(name = "PESSOA")
@Inheritance(strategy= InheritanceType.JOINED)
@SequenceGenerator(name = "Pessoa_seq")
@Proxy(lazy=false)
public class Pessoa implements Serializable {

    @Id
    @SequenceGenerator(name = "Pessoa_seq", sequenceName = "pessoa_seq", initialValue = 1, allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "Pessoa_seq")
    @Column(name = "PESSOA_ID", nullable = false)
    private int pessoaId;

    @Column(name = "EMAIL")
    private String email;

    @Column(name = "ENDERECO", length = 60)
    private String endereco;

    @Column(name = "BAIRRO", length = 60)
    private String bairro;

    @Column(name = "NUMERO", length = 15)
    private String numero;

    @Column(name = "COMPLEMENTO", length = 30)
    private String complemento;

    @Column(name = "OBSERVACAO", length = 300)
    private String observacao;

    @Column(name = "CEP", length = 10)
    private String cep;
    @Column(name = "NOME_RAZAO", nullable = false, length = 60)
    private String nomeRazao;

    @Column(name = "DATA_CAD")
    @Temporal(TemporalType.DATE)
    private Date dataCad;
    @Column(name = "TELEFONE")
    private String telefone;
    @Column(name = "CELULAR")
    private String celular;
    @Column(name = "FAX")
    private String fax;
    @Column(name = "DATA_NASC")
    @Temporal(TemporalType.DATE)
    private Date dataNasc;
  
    
    

    @OneToMany(mappedBy = "pessoaCliente", targetEntity = Cliente.class, fetch = FetchType.LAZY)
    @IndexColumn (name= "CLIENTE_INDEX")
    @Cascade(CascadeType.SAVE_UPDATE)
    private Collection<Cliente> cliente = new ArrayList<Cliente>();

    @ManyToOne
    @Cascade(value = CascadeType.SAVE_UPDATE)
    @JoinColumn(name = "PESSOA_CIDADE")
    @ForeignKey(name = "PESSOA_CIDADE_FK")
    private Cidade cidade;


    @ManyToMany
    @JoinTable(name = "PARTE_RE", schema = "SYSJURI",
    joinColumns =
    @JoinColumn(name = "PESSOA_ID"),
    inverseJoinColumns =
    @JoinColumn(name = "PROCESSO_ID"))
    private Set<Processo> processoRe = new HashSet<Processo>();

    @ManyToMany
    @JoinTable(name = "PARTE_AUTORA", schema = "SYSJURI",
    joinColumns =
    @JoinColumn(name = "PESSOA_ID"),
    inverseJoinColumns =
    @JoinColumn(name = "PROCESSO_ID"))
    private Set<Processo> processoAutor = new HashSet<Processo>();
Fisica
@Proxy(lazy=false)
@Entity
@Table(name = "FISICA")
@PrimaryKeyJoinColumn(name = "FISICA_ID")
@ForeignKey(name = "FISICA_PESSOA_FK")
public class Fisica extends Pessoa implements Serializable {

    @Column(name = "FISICA_ID", nullable = false, insertable = false, updatable = false)
    private int fisicaId;
    @Column(name = "CPF", length = 16, unique = true)
    private String cpf;
    @Column(name = "RG", length = 16)
    private String rg;
    @Column(name = "NACIONALIDADE", length = 40)
    private String nacionalidade;
    @Column(name = "NATURALIDADE", length = 40)
    private String naturalidade;
    @Column(name = "EST_CIVIL")
    private String estCivil;

    @OneToMany(mappedBy = "funcionarioFisica", targetEntity = Funcionario.class, fetch = FetchType.LAZY)
    @IndexColumn(name = "FUNC_INDEX")
    @Cascade(CascadeType.SAVE_UPDATE)
    private Collection<Funcionario> funcionario = new ArrayList<Funcionario>();

    @OneToMany(mappedBy = "advogadoFisica", targetEntity = Advogado.class, fetch = FetchType.LAZY)
    @IndexColumn(name = "ADV_INDEX")
    @Cascade(CascadeType.ALL)
    private Collection<Advogado> advogado = new ArrayList<Advogado>();

    @OneToMany(mappedBy = "fisica", fetch = FetchType.LAZY)
    @Cascade(CascadeType.SAVE_UPDATE)
    private Set<Juridica> juridica = new HashSet<Juridica>();

    @OneToMany(mappedBy = "pessoaUsuario", fetch = FetchType.LAZY)
    @IndexColumn (name= "USUARIO_INDEX")
    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    private Collection<Usuario> usuario = new ArrayList<Usuario>();

Juridica

@Entity
@Table (name = "JURIDICA")
@PrimaryKeyJoinColumn (name= "JURIDICA_ID")
@ForeignKey (name = "JURIDICA_PESSOA_FK")

public  class Juridica extends Pessoa implements Serializable {
    @Column (name = "JURIDCIA_ID", nullable= false)
    private int juridicaId;

    @Column (name = "CNPJ", length= 18, unique=true)
    private String cnpj;

    @Column (name = "INSC_EST", length=15)
    private String insc_est;

    @Column(name = "APELIDO_FANTASIA", length=60)
    private String apelidoFantasia;

    @ManyToOne 
    @Cascade (CascadeType.SAVE_UPDATE)
    @JoinColumn (name="REP_FISICO",updatable=true)
    @ForeignKey (name="JURIDICA_FISICA_FK")
    private Fisica fisica;

No iReport existe esse campo no meu relatorio :

CPF / CNPJ : $F{pessoaCliente}.getCpf() $F{pessoaCliente}.getCnpj()

A lista que passo no JRBeanCollectionDataSource

List pessoas = new ArrayList<Pessoa>();
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            Criteria c = session.createCriteria(Cliente.class);
            c.createCriteria("pessoaCliente",Criteria.INNER_JOIN);
            c.addOrder(Order.asc("pessoaCliente"));
            pessoas.addAll(c.list());

att.

rdmardegam

Amigo $F{pessoaCliente}.getCnpj não existe no jasper. Você nunca pode fazer get de algum atributo no jasper.

Voce tambem tem que declarar as informações que você quer utilizar no ireport individualmente.

Por exemplo: você está passando a lista List pessoas.

Os atributos da classe Pessoa são entre outros:

private int pessoaId;  
private String email;  
private String endereco;  
private String bairro;  
private String numero;
Entao no seu Ireport voce deve ter os fields assim:

$F{pessoaId}

$F{email}

$F{endereco}

$F{bairro}

$F{numero}

Voce nunca irá conseguir pegar a classe.get do atributo.

Enfim o erro ocorrerá pq o objeto Fisica não tem o Cnpj e o objeto Jurifica não tem o cpf. Então ao enviar a Lista de Pessoa e percorrela no ireport, ele sempre tentará recuperar o atributo que você informar, mas isso ocorrerá em erro !! Pois como ja disse os atributos estão em classes diferentes e o Ireport n consegue fazer o cast corretamente do objeto e verificar se o metodo existe. Ele simplesmente tenta executar o get e ve que não existe.

Até existe maneira de fazer isso, mas é mto trabalhoso e pode complicar um pko, acredito que seja com scriptlet.

Enfim, uma solucao rapida e simples seria vc na Classe Fisica apenas colocar um getCnpj() retornando “”;
E no objeto Juridica um getCpj() retornando tb “”;

Ou então fazer algo mais organizado que seria Criar um objeto somente para ser enviado para o Ireport, onde conteria todas as informações recuperadas da base que vc desejasse mostrar no Ireport e um campo cpnCnpj onde você trataria no java oque seria setado neste campo.

Ou então ainda, se sua pesquisa vier ordenada por pessoa fisica, so depois viessem todas as pessoas juridicas e vc conseguir contar quantas pessoas fisicas foram recuperadas, daria para fazer uma validacao no ireport para ele executar o getCpf até uma determinada repetição e so depois executar o getCnpj assim n tentando chamar o metodo de uma classe q n exista.
(ISSO N TENHO CERTEZA FOI UMA IDEIA Q TIVE)

N sei se fui mto claro hehe, qualquer coisa fala ae.

Qualquer coisa add no msn: [email removido]

Abraço

RicardoYukito

rdmardegam, foi super claro!

a ideia de colocar um retorno “” foi otima e funcionou.

mas vou tentar organizar melhor, como vou ter muitos outros relatorios nessa estrutura vou tentar criar uma classe pra manipular isso.

A, a questao do get, tambem achei um absurdo funcionar, fiz pensando que nao ia e fui surpreendido novamente! , mais até isso esta funcionando perfeitamente :
$F{pessoaCliente}.getCidade().getNomeEstado()

Vlw!

ajinfotec

como e ma o get funcionau cara como tu declarou o tipo do
$F{pessoaCliente} ja tentei fazer isso um monte de vez mas o ireport
nem se quer compila quem dirar executar.

rapaz explica isso ai como tu fez isso que ja penei para fazer e nada.

RicardoYukito

Eu crio um Field e coloco na propiedade Field Class o objeto que pertence a ele , por exempo no Field pessoaCliente defino o Field Class como Model.Pessoa (pacote.classe) ,
e no Text Field $F{pessoaCliente}.getNomeRazao , na propiedade Expression Class o tipo de dado que ele vai receber, no caso java.lang.String

ai na aplicação é só passar pro JRBeanCollectionDataSource, no meu caso, a lista de Cliente com seu objeto Pessoa.

ajinfotec

certo cara faço dessa forma mas na hora de compilar não compila no plugin do ireport para netbeans

ai turma alquem sabe o que e isso.

o ireport dis que não foi encontrado a classe.

RicardoYukito

Olha, eu uso a versao 3.7.4, mas acredito que a versão do ireport nao deve influenciar em nada…

voce adicionou o .jar do seu projeto no classpath do ireport ?
se tiver usando hibernate, adicionou a pasta com o hibernate.cfg.xml no classpath ?

tente adicionar essas bibliotecas no seu projeto , não é ctz mas tive um problema de nao executar porque estava usando uma versão mais antiga:
com-jaspersoft-ireport-jasperserver.jar
iText-2.1.7.jar

Criado 28 de julho de 2010
Ultima resposta 30 de jul. de 2010
Respostas 8
Participantes 3