quinta-feira, 7 de fevereiro de 2008

Novos horizontes

Devido a uma série de alterações no meu trabalho, volto somente agora a postar novos artigos.
A boa noticia é que estou refatorando o ITrust e devo escrever aqui as alterações que eu fiz e como isso pode lhe ajudar.

Eu mudei o servidor de aplicação, pois vamos trabalhar com EJB3, e isso sinceramente é muito bom.
Uma das vantagens de se usar EJB3 é que agora não precisamos mais controlar as transações, pois agora o container web vai fazer isso.
Vamos continuar usando Hibernate, porem não existe mais xml, vamos usar annotions ;-)
Basicamente vamos jogar muita coisa fora, pois até mesmo a abordagem do ITrust foi alterada.

Não pretendo mais fazer diretamente um ERP, mas sim um timesheet. É bem mais simples começar esse projeto fazendo um timesheet, pois a partir disso podemos posteriormente adicionar um controle financeiro, ou seja, vamos acoplar os módulos com o passar do tempo, mas o foco agora é fazer esse timesheet e como isso não é muito complicado eu já fiz uma grande parte.

Bom, chega de papo e vamos ao código.
Começando pelo mecanismo de persistência, vamos alterar um pouco nossas classes e também alguns conceitos que são o mais importante
Veja esse link e entenda o que é um repositório:
http://blog.fragmental.com.br/2007/03/01/voce-pergunta-001-daos-e-repositorios/

Espero que tenha entendido, portanto segue abaixo nossa definição do mecanismo de persistência, que é praticamente idêntico ao artigo que eu postei anteriormente, com algumas pequenas alterações, porem espero que o conceito tenha sido entendido.


package org.iprogramming.model.repository;

public interface GenericRepository<T> {
public void persist(T entity);
public void remove(T entity);
}

Acima vemos um repositório genérico, que será usado no nosso repositório de Login abaixo

package org.iprogramming.model.repository;

import java.util.List;
import org.iprogramming.model.entity.Login;

public interface LoginRepository extends GenericRepository<Login>{
public Login findById(Long id);
public Login findByName(String login);
public List<Login> list();
public List<Login> listOrderedBy(String column);
}


Pronto, nosso repositório ja esta definido, é apenas um conceito, onde nos definimos o que nosso repositório de Login deve fazer.
Quando estivermos fazendo nossos EJB, esses serão os nossos contratos para usar as classes abaixo


package org.iprogramming.model.persistence;

import javax.persistence.EntityManager;
import org.iprogramming.model.repository.GenericRepository;

public class GenericDAO<T, DAOImpl extends GenericRepository> implements GenericRepository<T>{

protected EntityManager em;

public DAOImpl setEntityManager(EntityManager em){
this.em = em;
return (DAOImpl)this;
}

public void persist(T entity){
em.persist(entity);
}

public void remove(T entity){
em.remove(entity);
}
}

Sim, novamente o nosso DAO genérico, porêm com menos funções, o exemplo é meramente demonstrativo, vc pode adicionar outras funções genéricas como bem entender.

package org.iprogramming.model.persistence;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import org.iprogramming.model.entity.Login;
import org.iprogramming.model.repository.LoginRepository;

public class LoginDAO extends GenericDAO<Login, LoginRepository> implements LoginRepository {

private static final Logger logger = Logger.getLogger(LoginDAO.class.getName());

private static final String msg = "Signals that a method has been invoked at an " +
"illegal or inappropriate time. In other words, the Java environment " +
"or Java application is not in an appropriate state for the requested operation";

public Login findById(Long id) {
return (Login)em.createNamedQuery("Login.findByPkLogin").
setParameter("pkLogin", id).getSingleResult();
}

public Login findByName(String name) {
try{
return (Login)em.createNamedQuery("Login.findByName").
setParameter("name", name).getSingleResult();
}catch(NoResultException e){
logger.log(Level.SEVERE, "Cannot find data");
throw new DAOException(e);
}catch(NonUniqueResultException e){
logger.log(Level.SEVERE, "Have more than one result");
throw new DAOException(e);
}catch(IllegalStateException e){
logger.log(Level.SEVERE, msg, e);
throw new DAOException(e);
}
}

public List<Login> list(){
try{
return em.createQuery("SELECT l FROM Login l").getResultList();
}catch(IllegalStateException e){
logger.log(Level.SEVERE, msg, e);
throw new DAOException(e);
}
}

public List<Login> listOrderedBy(String column) {
return em.createQuery("SELECT login FROM Login login order by login."+column).getResultList();
}
}

Ok, terminamos o nosso mecanismo de persistencia para a entidade login. Segue abaixo a entidade login porem agora estamos usando anotações.

package org.iprogramming.model.entity;

import java.io.Serializable;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;


@Entity
@Table(name = "login")
@NamedQueries({
@NamedQuery(name = "Login.findByPkLogin",query = "SELECT l FROM Login l WHERE l.pkLogin = :pkLogin"),
@NamedQuery(name = "Login.findByName",query = "SELECT l FROM Login l WHERE l.name = :name"),
@NamedQuery(name = "Login.findByPassword",query = "SELECT l FROM Login l WHERE l.password = :password"),
@NamedQuery(name = "Login.findByEmail",query = "SELECT l FROM Login l WHERE l.email = :email"),
@NamedQuery(name = "Login.findByTelephone",query = "SELECT l FROM Login l WHERE l.telephone = :telephone"),
@NamedQuery(name = "Login.findByDescription",query = "SELECT l FROM Login l WHERE l.description = :description")})

public class Login implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@Column(name = "pk_login", nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="seq_login")
@SequenceGenerator(name="seq_login", sequenceName="seq_login", allocationSize=1)
private Integer pkLogin;

@Column(name = "name", nullable = false)
private String name;
@Column(name = "password", nullable = false)
private String password;
@Column(name = "email", nullable = false)
private String email;
@Column(name = "telephone", nullable = false)
private String telephone;
@Column(name = "description")
private String description;
@JoinTable(name = "login_x_role", joinColumns = {@JoinColumn(name = "fk_login", referencedColumnName = "pk_login")}, inverseJoinColumns = {@JoinColumn(name = "fk_role", referencedColumnName = "pk_role")})
@ManyToMany
private Collection fkRoleCollection;
@JoinTable(name = "login_x_page", joinColumns = {@JoinColumn(name = "fk_login", referencedColumnName = "pk_login")}, inverseJoinColumns = {@JoinColumn(name = "fk_page", referencedColumnName = "pk_page")})
@ManyToMany
private Collection fkPageCollection;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "fkLogin")
private Collection timesheetCollection;

public Login() {
}

public Login(Integer pkLogin) {
this.pkLogin = pkLogin;
}

public Login(Integer pkLogin, String name, String password, String email, String telephone) {
this.pkLogin = pkLogin;
this.name = name;
this.password = password;
this.email = email;
this.telephone = telephone;
}

public Integer getPkLogin() {
return pkLogin;
}

public void setPkLogin(Integer pkLogin) {
this.pkLogin = pkLogin;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getTelephone() {
return telephone;
}

public void setTelephone(String telephone) {
this.telephone = telephone;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public Collection getFkRoleCollection() {
return fkRoleCollection;
}

public void setFkRoleCollection(Collection fkRoleCollection) {
this.fkRoleCollection = fkRoleCollection;
}

public Collection getFkPageCollection() {
return fkPageCollection;
}

public void setFkPageCollection(Collection fkPageCollection) {
this.fkPageCollection = fkPageCollection;
}

public Collection getTimesheetCollection() {
return timesheetCollection;
}

public void setTimesheetCollection(Collection timesheetCollection) {
this.timesheetCollection = timesheetCollection;
}

@Override
public int hashCode() {
int hash = 0;
hash += (pkLogin != null ? pkLogin.hashCode() : 0);
return hash;
}

@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Login)) {
return false;
}
Login other = (Login) object;
if ((this.pkLogin == null && other.pkLogin != null) || (this.pkLogin != null && !this.pkLogin.equals(other.pkLogin))) {
return false;
}
return true;
}

@Override
public String toString() {
return "org.iprogramming.model.entity.Login[pkLogin=" + pkLogin + "]";
}

}

Ok, chegamos ao fim desse artigo, no proximo vou usar esse mecanismo através de um EJB e vou descrever como devemos injetar o EntityManager em nossos mecanismos de persistencia.

Nenhum comentário: