uaiMockServer – Create a Mock Rest Server with a single command line

0

Posted on by

Share it now!

Hello how are you?

Have you ever needed to invoke a REST service, but this service was not created yet?

Imagine that you are developing an APP that needs to invoke an inexistent REST service. You will need to create a fake code that will be replaced once that the real code is finished. No matter if you are working with Java, .NET, PHP, Ruby, Python, etc. You will always need to create a fake invocation method if the REST service is not ready yet.

When we are programming in our unitary test we face the same problem. We will need to create a Mock code that will be invoked during the tests. The problem with this approach is that the real code is never invoked.

How can we solve this problem? Is there a solution that works for delphi, .NET, PHP, Java, Android, IOS, WindowsPhone, etc?

I present to you now my most recent creation: “uaiMockServer”.

With uaiMockServer you will be create a mock server using only a JAR file and a config file. With this server you will be able to execute real HTTP requests, but using your test data.

There are two ways of using uaiMockServer: Standalone and Unit Tests

Standalone

To use the uaiMockServer as a Standalone server you will manually type the command that starts it. Run the command in a prompt:

java -jar uaiMockServer-{VERSION}.Standalone.jar

You will only need the config file, that we will talk about very soon.

In the sample config file there is a mapping using the port 1234. If you are using linux, type the command:

curl localhost:1234/uaiMockServer/

The HTTP Response will contain a JSON.

Unit Test

First step is to add the project in your pom:

<dependency>
   <groupId>uaihebert.com</groupId>
   <artifactId>uaiMockServer</artifactId>
   <version>1.0.1</version>
   <scope>test</scope>
</dependency>

Now you can create a test code like:

public class YourTest {
    private static UaiMockServer uaiMockServer;
 
    @BeforeClass
    public static void beforeClass() {
        uaiMockServer = UaiMockServer.start();
    }
 
    @AfterClass
    public static void afterClass() {
        uaiMockServer.shutdown();
    }
 
    @Test
    public void aTest() {
        final Customer customer = // invoke the URL
        assertTrue(customer != null);
    }
}

You will be able to invoke the URL using any kind of framework. Below you will see a code sample using the RestEasy framework doing a request mapped in the sample config file (that we will see soon):

@Test
public void isGetRootReturning200() {
    final String url = "http://localhost:1234/uaiMockServer/";
 
    Client client = ClientBuilder.newClient();
    Response response = client.target(url).request().get();
 
    assertEquals(200, response.getStatus());
}

What is the gain in the test? You will not need a mock code anymore. You can fire a HTTP request from your JUnit test.

Configuration

To run the project you will need a config file. A simple sample would be like below:

com.uaihebert.uaimockserver {
    port = 1234
    host = localhost
    fileLog = false
    consoleLog = true
    context = /uaiMockServer
    defaultContentTypeResponse = "text/html;charset=UTF-8"
    routes = [
        {
            request {
                path = "/"
                method = "GET"
            }
            response {
                contentType = "application/json;charset=UTF-8"
                statusCode = 200
                body = """{"mockBody":{"title":"Hello World"}}"""
            }
        }
    ]
}

The file must have the .config extension and is not in the JSON format, but has a superset format of the JSON – HCON – used in configurations files (click here for more details).

With this file you can set up the port that will be invoked, the host, header, queryParm and other several options that are described in the uaiMockServer documentation.

Notice that in the configuration was created a request and a response; with these configurations you can mock every request that you want.

If you are going to use the Standalone version the config file must be in the same directory of the JAR file. You can set a different path with the command:

java -jar uaiMockServer-{VERSION}.Standalone.jar FULL_FILE_PATH

If you will run the project in your Unit Tests (like JUnit) you must put the config file in the “src/test/resources” maven folder. Or you can pass the full path like:

uaiMockServer = UaiMockServer.start(FULL_FILE_PATH);

It is free?

Yes, it is. Use it at your will.

Is open source? Yes: https://github.com/uaihebert/uaiMockServer

Where is the documentation? http://uaimockserver.com/

Where can I find the Standalone and the sample Config file: http://sourceforge.net/projects/uaimockserver/files/

It has any automated test? Yes, we have a lot of tests and we got 100% code coverage.

What about performance?

In the GIT there is a test that executes 300 requests in less than 2s.

Thanks to:

uaiMockServer – Crie um servidor Rest de teste com apenas uma linha de comando

4

Posted on by

Share it now!

Olá, tudo bem?

Sabe aquele momento em que você precisa chamar um serviço REST, mas esse serviço não está pronto ainda?

Imagine que você está desenvolvendo uma nova tela do APP que o serviço REST ainda não está pronto. Nesse caso você precisará ter um código falso em seu projeto, e esse código terá que ser substituído quando o serviço ficar pronto. Não importa se você trabalha com Java, .NET, PHP, Ruby, Python, etc.. Você terá que ter sempre o trabalho de primeiro criar o mock e depois criar a chamada real quando o serviço REST não estiver pronto.

Para testes unitários temos o mesmo problema, é comum termos uma classe com a implementação real e uma classe com um código falso. Na hora do teste é que a classe falsa é utilizada. O ruim dessa abordagem é que o código que executa a chamada nunca é testado.

Como podemos resolver esse problema? E o mais interessante: “existe uma solução que atenda delphi, .NET, PHP, Java, Android, IOS, WindowsPhone, etc?”

Apresento para vocês o mais novo produto que criei: “uaiMockServer

Com o uaiMockServer você poderá criar um servidor de teste utilizando o JAR e um arquivo de configuração. Com o uaiMockServer você poderá disparar os testes usando HTTP, mas com seus dados de testes.

Existem dois modos de utilizar o uaiMockServer: Standalone e com Testes Unitários.

Standalone

O modo standalone é quando você dispara o jar manualmente. Para executar o serviço manualmente basta fazer:

java -jar uaiMockServer-{VERSION}.Standalone.jar

Tudo o que você precisa agora é do arquivo de configuração que estará descrito mais abaixo.

No arquivo exemplo de configuração já vem mapeado um hello world apontando para a porta 1234. Se você estiver usando linux, execute o comando:

curl localhost:1234/uaiMockServer/

E você já verá o JSON retornado.

Testes Unitários

Primeiro passo é adicionar o projeto em seu pom:

<dependency>
   <groupId>uaihebert.com</groupId>
   <artifactId>uaiMockServer</artifactId>
   <version>1.0.1</version>
   <scope>test</scope>
</dependency>

Uma vez que a dependência já está em seu pom você pode criar um teste como o abaixo:

public class YourTest {
    private static UaiMockServer uaiMockServer;

    @BeforeClass
    public static void beforeClass() {
        uaiMockServer = UaiMockServer.start();
    }

    @AfterClass
    public static void afterClass() {
        uaiMockServer.shutdown();
    }

    @Test
    public void aTest() {
        final Customer customer = // invoke the URL
        assertTrue(customer != null);
    }
}

A chamada na URL tem que ser feita com algum framework de sua preferência. Eu coloco abaixo um exemplo feito utilizando RestEasy e o arquivo de configuração (mostrado mais abaixo):

@Test
public void isGetRootReturning200() {
    final String url = "http://localhost:1234/uaiMockServer/";

    Client client = ClientBuilder.newClient();
    Response response = client.target(url).request().get();

    assertEquals(200, response.getStatus());
}

A vantagem disso? Agora você não precisa mais de um código mock em seus testes. Você pode chamar diretamente do JUnit o servidor criado.

Configuração

Para rodar corretamente é necessário um arquivo de configuração. Um exemplo simples seria o arquivo abaixo:

com.uaihebert.uaimockserver {
	port = 1234
	host = localhost
	fileLog = false
	consoleLog = true
	context = /uaiMockServer
	defaultContentTypeResponse = "text/html;charset=UTF-8"
	routes = [
	    {
			request {
				path = "/"
				method = "GET"
			}
			response {
				contentType = "application/json;charset=UTF-8"
				statusCode = 200
				body = """{"mockBody":{"title":"Hello World"}}"""
			}
	    }
    ]
}

O arquivo tem que ter a extensão .config e não está no formato JSON, mas sim é um superset do JSON – HCON – utilizado para configurações (clique aqui para mais detalhes).

Com esse arquivo você pode configurar a porta a ser chamada, o host, header, queryparam e diversas outras funções que estão descritas na documentação do uaiMockServer.

Note que foi criado um request e response desse modo você pode simular toda chamada que você quiser.

Caso você rode a versão Standalone, esse arquivo deve ficar na mesma pasta que o jar. Você também pode passar o caminho completo assim:

java -jar uaiMockServer-{VERSION}.Standalone.jar CAMINHO_COMPLETO_DO_ARQUIVO

Caso você vá rodar o serviço em seus testes unitários (JUnit por exemplo), você deve colocar o arquivo na pasta “src/test/resources” do maven. Você também poderia passar o caminho completo do arquivo como:

uaiMockServer = UaiMockServer.start(CAMINHO_COMPLETO_DO_ARQUIVO);

É grátis?

Sim. Use a vontade.

O código fonte é aberto? Sim: https://github.com/uaihebert/uaiMockServer

A documentação está onde? http://uaimockserver.com

E para baixar o .config e o JAR Standalone? http://sourceforge.net/projects/uaimockserver/files/

Tem teste? Sim, Temos bastantes testes unitários e 100% de cobertura.

Performance desse trem é bom?

No próprio GIT tem um teste que dispara 300 requests e tem todas as resposta em menos de 2 segundos.

Agradecimentos Especiais

Be a Developer, not a Blender

2

Posted on by

Share it now!

Hello, how are you?

We live in a “frameworks that are easy to use” age that helps us to create our projects. One thing that a lot of teachers say is: “Just use this annotation and it will be ok”.

Annotations have the objective of making frameworks easier to use and identify their behavior, but some developers get lost with this feature and and they forget about some of the OO basics.

CRUD, JMS queues, Beans, transaction controls can be created in minutes, but what about the Object Orientation? What happened with the good practices that took a long time to be correctly forged? Why are they being abandoned?

Mixing Concepts

To understand better what I am trying to say, let us see below some code snippets  that we find in development sites. In the first sample we can see a code with JPA and JSON mixed:

@Entity
@XmlRootElement
@JsonAutoDetect
@DiscriminatorColumn(name = "animal_type")
@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Dog.class, name = "dog"),
        @JsonSubTypes.Type(value = Cat.class, name = "cat"),
        @JsonSubTypes.Type(value = Bird.class, name = "bird")
})
public class Animal {
 
    @Id
    private int id;
 
    @JsonSerialize(using = JsonDateSerializer.class)
    private Date birthday;
 
    @JsonView(ToothView.class)
    @OneToMany(mappedBy = "animal")
    private List<Tooth> teethList;
 
    // other stuff
}
 
@Entity
@JsonRootName(value = "Dog")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Dog extends Animal {
 
    @JsonProperty
    private String name;
 
    @Convert(converter = JsonAttributeConverter.class)
    private Double weight;
 
    @JsonIgnore
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "dog", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Bone> boneList;
 
    public Dog() {
    }
}

What is the problem with the code above? Why would someone mix JSON annotations (VIEW) with JPA annotations (MODEL)? If we need to edit an attribute only to display it in a different way in a VIEW, this update will affect the same class that is used to persist the data. We will increase the risk to input a bug when persisting the data.

No Respect for the Layers

Let us see another example:

@ViewScoped
@ManagedBean
@TransactionManagement(TransactionManagementType.BEAN)
public class ManagedBeanOne extends SuperManagedBean implements Serializable {
     // attributes
    public String doSomething() {
        try{
            transaction.begin();
            // do something
            transaction.commit();
        }
        catch(Exception ex){
            transaction.rollback();
        }
    }
}
 
 
@ManagedBean
@WebService
@ViewScoped
public class ManagedBeanTwo implements Serializable{}

Should the class be defined as a JSF ManagedBean and an EJB? The worst part of this code is: Why is a JSF class managing a transaction? What do we gain by giving this ManagedBean so many responsibilities?

Huge Code Blocks Do Not Help

A code that I could not post here is a class with more than 1k lines. The worst part of a huge class is that the some developers start to make jokes about it, or sometimes the class is considered to be a huge bad monster that should never be touched because any update would break the code.

How long will developers keep adding just one if statement to this kind of classes without doing small refactorings?

Exception that Dictate the Rules

A terrible practice is using an Exception to handle the request flow. Take a look below:

try{
    myObject.doSomething();
} catch(MyExceptionOne one){
    sendErrorSmsToCustomer();
    defineOldPlanToCustomer();
    sentToScreenOne();
} catch(MyExceptionTwo two){
    sendErrorEmailToCustomer();
    defineNewPlanToCustomer();
    sentToScreenTwo();
}

What would happen with the database data if an error is thrown at the first line of the exception block? What would happen if a developer invokes “myObject.doSomething()” in another class but without the correct catch code like above? What if the line code that handles the user plan is not executed?

What comes next?

It is an easy task to say if code looks good or bad, but I believe that one thing that is needed is to always to show a solution. What we will see in the pages to come is not something created by me, but are good practices and design patterns that you will find in several development books.

What we will see:

  • Page 2: Do not Pass Over the Layers
    • Pay Attention to the Packages
  • Page 3: Increase your Cohesion
  • Page 4: Loose Coupling
    • Facade is a Good Call
  • Page 5: Let us Return to the DTOs World
    • How can I easily pass the Entity data to a DTO?
  • Page 6: Small Classes and Methods
  • Page 7: How can we use Exceptions Correctly?
  • Page 8: The Broken Window Theory
    • Keep your build working
    • Do not leave your tests breaking
    • Do not comment/ignore your tests
  • Page 9: Good practices that helps
    • KISS
    • DRY
  • Page 10: It does not matter if you have a huge amount of tests without quality
    • Use Test Tools
    • Did you find a bug? Create a test for it
  • Page 11: Conclusion

I hope that this posts helps you. (:

I am really thankful for the Rodrigo Sasaki’s (http://cv.rodrigosasaki.com) help, this guy rocks!

Seja um Desenvolvedor, não um liquidificador

28

Posted on by

Share it now!

Olá, tudo bem?

Vivemos em uma época onde é muito fácil de criar projetos com frameworks “mágicos”. O que é ensinado em diversos blogs e faculdades é que: “basta anotar com isso aqui que está pronto”.

Anotações tem a função de facilitar a utilização e a identificação de comportamentos dos frameworks, mas existem desenvolvedores que se perdem com essa facilidade e acabam esquecendo de conceitos básicos.

CRUD, filas JMS, Beans, controle de transações podem ser criados em minutos, mas e a parte de Orientação a Objeto? Conceitos básicos do Java? O que tem acontecido para que as boas práticas que demoraram anos para serem desenvolvidas simplesmente serem abandonadas?

Misturando Conceitos

Para ser mais claro, vamos ver alguns exemplos de códigos postados por desenvolvedores em fóruns. No primeiro exemplo é possível ver a mistura de JPA com JSON:

@Entity
@XmlRootElement
@JsonAutoDetect
@DiscriminatorColumn(name = "animal_type")
@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Dog.class, name = "dog"),
        @JsonSubTypes.Type(value = Cat.class, name = "cat"),
        @JsonSubTypes.Type(value = Bird.class, name = "bird")
})
public class Animal {

    @Id
    private int id;

    @JsonSerialize(using = JsonDateSerializer.class)
    private Date birthday;

    @JsonView(ToothView.class)
    @OneToMany(mappedBy = "animal")
    private List<Tooth> teethList;

    // other stuff
}

@Entity
@JsonRootName(value = "Dog")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Dog extends Animal {

    @JsonProperty
    private String name;

    @Convert(converter = JsonAttributeConverter.class)
    private Double weight;

    @JsonIgnore
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "dog", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Bone> boneList;

    public Dog() {
    }
}

Qual o problema do código acima? Qual o motivo da mistura de anotações de JSON (view) com anotações do JPA (modelo)? Note que, por causa dessa mistura, qualquer campo que a view deva exibir de modo diferente afetará justamente a mesma classe utilizada para salvar dados no banco de dados.

Não respeitando as camadas

Vamos a outro exemplo:

@ViewScoped
@ManagedBean
@TransactionManagement(TransactionManagementType.BEAN)
public class ManagedBeanOne extends SuperManagedBean implements Serializable {
     // attributes
    public String doSomething() {
        try{
            transaction.begin(); 
            // do something
            transaction.commit();
        }
        catch(Exception ex){
            transaction.rollback();
        }
    }
}


@ManagedBean
@WebService
@ViewScoped
public class ManagedBeanTwo implements Serializable{}

Por que fazer de um ManagedBean de JSF também como um EJB? E até pior, por que deixar que um ManagedBean controle uma transação? Qual o ganho em deixar o ManagedBean com diversas responsabilidades?

Tamanho mais atrapalha que ajuda

Um exemplo que eu não tive como colocar aqui foi de uma classe com mais de 1k de linhas. A pior parte é saber que esse tipo de classe fica sempre como motivo de chacota, ou essa classe é tratada como um objeto de terror e espanto pois qualquer alteração quebra o sistema.

Até quando os desenvolvedores vão ter o hábito de sempre querer adicionar um if sem antes fazer um pequeno refactoring?

Exception que é Chefe

Outra prática terrível é deixar uma exceção controlar o fluxo. Veja como é fácil cometer esse erro:

try{
    myObject.doSomething();
} catch(MyExceptionOne one){
    sendErrorSmsToCustomer();
    defineOldPlanToCustomer();
    sentToScreenOne();
} catch(MyExceptionTwo two){
    sendErrorEmailToCustomer();
    defineNewPlanToCustomer();
    sentToScreenTwo();
}

No exemplo acima, o que aconteceria com os dados do banco se na primeira linha de uma exceção acontecesse um erro? O que aconteceria se algum desenvolvedor fosse executar a chamada myObject.doSomething(); em alguma outra classe, e não tratasse todos os erros como no exemplo acima? E se ele não adicionasse a linha onde não trata o plano do usuário?

E agora?

Falar dos problemas é fácil, mas eu creio que ser necessário mostrar soluções que podemos aplicar em nosso dia a dia para melhorar a qualidade de código. O que vamos ver nas próximas páginas não é nada inventado por mim, mas são práticas extraídas de livros sobre design patterns e boas práticas de programação.

O que veremos:

  • Página 2: Não transpasse camadas
    • Atenção nos pacotes
  • Página 3: Aumente a coesão
  • Página 4: Reduza o acoplamento
    • Facade é uma boa pedida
  • Página 5: Voltemos ao mundo dos DTOs
    • Como facilitar a cópia de uma Entity para um DTO
  • Página 6: Métodos e Classes pequenas
  • Página 7: Como usar exceção corretamente?
  • Página 8: Teoria da Janela quebrada
    • Mantenha seu build sempre funcionando
    • Nunca deixe testes quebrados
    • Não comente/ignore seus testes
  • Página 9: Boas práticas que ajudam
    • KISS
    • DRY
  • Página 10: Quantidade de testes não importa, mas sim a qualidade
    • Utilize ferramentas
    • Achou um bug? Crie um teste
  • Página 11: Conclusão

Espero que este post seja útil ao seu dia a dia. (:

Não poderia deixar de agradecer ao Rodrigo Sasaki (http://cv.rodrigosasaki.com/) que me deu uma força absurda na revisão do post.

EasyCriteria evoluiu para uaiCriteria. Novo nome e novas funcionalidades

4

Posted on by

Share it now!

Olá, tudo bem?

É com muita felicidade que venho anunciar o uaiCriteria, a evolução do EasyCriteria.

Por que a mudança de nome? Descobri que já existia no mercado um framework com o mesmo nome e para evitar qualquer problema eu resolvi mudar o nome do framework. A diferença é que o uaiCriteria trabalha com String como parâmetro, e o outro framework trabalha com MetaModel diretamente.

Para esclarecer algumas dúvidas sobre a mudança:

  • Seu código antigo continuará funcionando sem problema algum, o código é retro compatível

  • As classes EasyCriteira estão marcadas com @Deprecated e serão removidas na próxima versão

  • As novas classes tem os mesmo métodos que as antigas e muitas outras novidades. Basta fazer um “replace” de EasyCriteria por UaiCriteria e todo problema estará resolvido

  • Novamente, eu não queria mudar o nome mas também não quero problemas com outras pessoas

O framework também ganhou um mascote, eu espero que vocês gostem:

mascote

mascote

De novidades temos muitas, mas muitas mesmo! Vamos ver primeiro mudanças de estrutura:

  1. O site mudou, agora o site é o: http://uaicriteria.com

  2. O repositório mudou, agora estamos hospedados no GIT. Após diversos pedidos movi para o GIT para melhorar a visualização do código: https://github.com/uaihebert/uaicriteria

  3. Para ajudar na cobertura do código e análise estática foi adicionado o plugin do SONAR. A imagem de cobertura agora ficou até mais bonita:

    uaicriteria cobertura

    uaicriteria cobertura

  4. O site antigo será desativado e todos os dados antigos foram levados para site novo, até mesmo a documentação legada. [=

  5. A API atual existe limitações, algo como não possibilitar o uso do HAVING e algumas outras funções, desse modo será criada para próxima versão uma Interface/API para Criterias Complexas – aceito sugestão de nome para a Interface (:

Com relação ao código, temos diversas novidades:

Boas vindas ao Batoo

O Batoo é um provedor de JPA assim como EclipseLink ou Hibernate. Com essa nova versão diversas funcionalidades foram cobertas com o Batoo.

Note que eu disse diversas, mas não todas. Infelizmente o Batoo ainda tem muitos, mas muitos problemas mesmo com consultas e Criterias.

O uaiCriteria ainda dá cobertura aos frameworks Hibernate, EclipseLink e OpenJPA na maioria dos métodos.

MultiSelect

É possível escolher quais campos serão retornados em uma consulta, veja a JPQL:

select 
    p.name, 
    p.age

from Person p

Transformando a consulta acima em criteria:

final UaiCriteria<Person> uaicriteria = 
    UaiCriteriaFactory.UaiCriteriaFactory.createMultiSelectCriteria(entityManager, Person.class);

uaiCriteria.addMultiSelectAttribute("name")
           .addMultiSelectAttribute("age");

final List multiselectList = uaiCriteria.getMultiSelectResult();

Algumas considerações sobre o código acima:

  • O resultado terá um Object caso você retorne apenas um campo

  • O resultado terá um Object[] caso você retorne diversos campos

  • A implementação pode variar de Object[] ou Vector (pelo menos comigo o EclipseLink estava retornando Vector)

SubQuery

Agora é possível fazer subQuery. Imagine uma JPQL como a abaixo:

select p from Person p 
where p.id in 
        (select dog.person.id from Dog dog where dog.cute = true)

Nem vou citar quantas linhas de código seriam necessárias para fazer o código acima, mas com o UaiCriteria ficou bem mais fácil:

final UaiCriteria<Person> uaiCriteria = UaiCriteriaFactory.createQueryCriteria(Person.class);

final UaiCriteria<Dog> subQuery = uaiCriteria.subQuery("person.id", Dog.class); // dog.person.id

subQuery.andEquals("cute", true);

uaiCriteria.andAttributeIn("id", subQuery); //person.id

Basta criar um objeto de subQuery passando qual será o retorno da subQuery. Depois chame o método o attributeIn(…) da query principal passando qual o campo a ser comparado.

MapIsEmpty [NOT]

Agora é possível utilizar a função isEmpty com Map:

uaiCriteria.andCollectionIsEmpty("ENTITY_MAP");

AttributeIn [NOT]

Existe a opção de verificar se um valor está ou não dentro de uma lista. Veja o exemplo abaixo:

select p
from Payment p
where
    p.statusEnum in :enumList

Para transformar o código acima em criteria:

final UaiCriteria<Payment> uaiCriteria = 
    UaiCriteriaFactory.createQueryCriteria(Payment.class);

uaiCriteria.andAttributeIn("statusEnum", 
                           Arrays.asList(StatusEnum.VALUE_01, StatusEnum.VALUE_02));

O atributo não precisa ser necessariamente um enum, poder ser número, string, etc.

MemberOf [NOT]

A consulta abaixo

select d
from Departament d
where :person member of d.employeeList

Pode ser criada como:

final UaiCriteria<Departament> uaiCriteria = UaiCriteriaFactory.createQueryCriteria(Departament.class);

uaiCriteria.andIsMemberOf(person, "employeeList");

Count e CountRegularCriteria

Agora como é possível realizar uma consulta MultiSelect o método count() foi renomeado como countRegularCriteria(). Funciona do mesmo modo, houve apenas uma alteração no nome para ficar mais claro seu funcionamento.

CountAttribute

Existe situações onde é necessário realizar o count em cima de um atributo, algo como:

select count(p.id)
from Person p

E para executar como Criteria:

final UaiCriteria<Person> uaiCriteria = 
    UaiCriteriaFactory.createMultiSelectCriteria(Person.class);

uaiCriteria.countAttribute("id");

final List result = uaiCriteria.getMultiSelectResult();

GroupBy e funções de Agregação

Agora é possível realizar groupBy juntamente com diversas funções de agregação. Funções como sum, diff, divide, module, etc.

select sum(p.value), p.status
from Payment p
group by p.status

Poderia se executada como:

final UaiCriteria<Payment> uaiCriteria = 
    UaiCriteriaFactory.createMultiSelectCriteria(Payment.class);

uaiCriteria.sum("id").groupBy("status");

final List result = uaiCriteria.getMultiSelectResult();

Novo Import no Maven

Para utilizar a nova versão em seu projeto, basta adicionar o código abaixo ao seu pom.xml

<dependency>
    <groupId>uaihebert.com</groupId>
    <artifactId>uaiCriteria</artifactId>
    <version>4.0.0</version>
</dependency>

Bem, espero que você tenha gostado das novidades.

Não esqueça de visitar o site —————-> http://uaicriteria.com

Qualquer dúvida/crítica/sugestão basta falar.

Até mais. \o_

EasyCriteria has evolved to uaiCriteria. New name and more features

0

Posted on by

Share it now!

Hello, how are you?

I am very happy to announce the release of the uaiCriteria, the EasyCriteria evolution.

Was it really needed to change the framework name? Yes, sadly it was. I found another framework with the same name, that is why I decided to change the name (I do not want any kind of legal problems). The difference of the framework is that the other framework works with MetaModel, and uaiCriteria works with strings as parameters.

About the framework name change:

  • Your code will work with this new version without a problem, the code is retro compatible
  • All EasyCriteria classes are annotated with @Deprecated and will be removed in the next version
  • The new classes has all the methods of the old version. If you want to change for the new code just “replace” the text EasyCriteria for UaiCriteria in your code
  • Again, I did not want to change the framework name but I do not want legal problems

The framework now has a mascot:

mascot

mascot

The new version has a lot of new stuff. Let us talk first about the structural changes:

  • The site has changed, now is http://uaicriteria.com
  • The repository has changed, now is on GIT (requested by a lot of develpers) https://github.com/uaihebert/uaicriteria
  • The SONAR plug-in was added to the pom.xml to help with code the code coverage and static analysis:

    uaicriteria cobertura

    uaicriteria cobertura

  • The old site will be deactivated, but all the old documentation was migrated.
  • The current API has some criteria limitations, using HAVING in the criteria is something that is not possible. We will create a new Interface/API to use with complex criteria – I am looking for a new name for the new Interface, could you suggest me one? (:

Let us talk about the new features:

Welcome to Batoo

Batoo is a JPA provider like EclipseLink or Hibernate. In this new version we got a good number of methods tested with Batoo.

Notice that I talked about “a good number of methods” but not most of the methods. Unfortunately Batoo has several problems with JPQL and Criterias, and I could not cover most of the methods with it.

uaiCriteria framework support almost all methods with EclipseLink, Hibernate and OpenJPA.

MultiSelect

It is possible to choose which attributes will be returned:

select
    p.name,
    p.age
from 
    Person p

If we transform the JPQL above in Criteria:

finalUaiCriteria<Person> uaicriteria =
    UaiCriteriaFactory.UaiCriteriaFactory.createMultiSelectCriteria(entityManager, Person.class);

uaiCriteria.addMultiSelectAttribute("name")
           .addMultiSelectAttribute("age");

finalList multiselectList = uaiCriteria.getMultiSelectResult();

Some considerations about the code above:

  • Object will be returned if you select only one attribute
  • Object[] will be returned if you select more than one attribute
  • The JPA provider may return Vector instead of Object[] (with my tests EclipseLink was returning a Vector)

SubQuery

Now it is possible to do a subQuery like below:

select p from Person p 
where p.id in
        (select dog.person.id from Dog dog where dog.cute = true)

I will not talk about the several lines of native JPA criteria needed to do the JPQL above, but with UaiCriteria is very easy to do:

final UaiCriteria<Person> uaiCriteria = UaiCriteriaFactory.createQueryCriteria(Person.class);
 
final UaiCriteria<Dog> subQuery = uaiCriteria.subQuery("person.id", Dog.class); // dog.person.id
 
subQuery.andEquals("cute", true);
 
uaiCriteria.andAttributeIn("id", subQuery); //person.id

All you need to do is to create a subQuery informing its return; then call the method attributeIn of the root criteria.

MapIsEmpty [NOT]

The isEmpty method can be used with maps:

uaiCriteria.andCollectionIsEmpty("ENTITY_MAP");

AttributeIn [NOT]

If you want to validate if a value is inside a list like the JPQL:

select p
from Payment p
where
    p.statusEnum in :enumList

You can create the JPQL above like:

final UaiCriteria<Payment> uaiCriteria = 
    UaiCriteriaFactory.createQueryCriteria(Payment.class);
 
uaiCriteria.andAttributeIn("statusEnum", 
                           Arrays.asList(StatusEnum.VALUE_01, StatusEnum.VALUE_02));

The attribute could be a enum, integer, String, etc.

MemberOf [NOT]

The query below:

select d
from Departament d
where :person member of d.employeeList

Could be created like:

final UaiCriteria<Departament> uaiCriteria = 
    UaiCriteriaFactory.createQueryCriteria(Departament.class);
 
uaiCriteria.andIsMemberOf(person, "employeeList");

Count and CountRegularCriteria

Now it is possible to do a count with a MultiSelect criteria. The count method was renamed to countRegularCriteria(). It works like the older version, just the name was refactored to make things more distinct.

CountAttribute

Sometimes you need to count an attribute instead of an entity:

select count(p.id)
from Person p

You can run the JPQL above like:

final UaiCriteria<Person> uaiCriteria = 
    UaiCriteriaFactory.createMultiSelectCriteria(Person.class);
 
uaiCriteria.countAttribute("id");
 
final List result = uaiCriteria.getMultiSelectResult();

GroupBy and Aggregate Functions

Now it is possible to do a GroupBy with aggregate functions: sum, diff, divide, module,  etc.

select sum(p.value), p.status
from Payment p
group by p.status

Could be executed like:

final UaiCriteria<Payment> uaiCriteria = 
    UaiCriteriaFactory.createMultiSelectCriteria(Payment.class);
 
uaiCriteria.sum("id").groupBy("status");
 
final List result = uaiCriteria.getMultiSelectResult();

New Maven Import

If you want to use the new version, just add the xml below to your pom.xml:

<dependency>
    <groupId>uaihebert.com</groupId>
    <artifactId>uaiCriteria</artifactId>
    <version>4.0.0</version>
</dependency>

I hope you liked the news.

Do not forget to visit the new site ———–> http://uaicriteria.com

If you have any doubts, questions or suggestions just post it.

See you soon. \o_

Alternativas ao JPA Hibernate. O que usar quando o JPA não atende meu projeto?

20

Posted on by

Share it now!

Olá, tudo bem?

Hoje vamos falar sobre situações onde o JPA pode não nos atender. Com quais alternativas podemos contar a partir do momento que percebemos que o JPA não está ajudando?

O que vamos ver aqui hoje:

  • Problemas do JPA e do Hibernate
  • Soluções para problemas do JPA
  • Critérios para escolha dos frameworks descritos aqui
  • Spring JDBC Template
  • MyBatis
  • Sormula
  • sql2o
  • Vale a pena conferir: jOOQ e Avaje
  • E o JDBC puro? Ainda vale a pena?
  • Considerações sobre qual framework escolher
  • Conclusão

Criei em meu github 4 CRUDS completos das ferramentas detalhadas aqui no post, cada URL está em cada página que descreve o framework.

Eu não sou o tipo de pessoa radical que acha que o JPA não serve para nada, pelo contrário, creio que em determinados momentos é necessário escolher o framework mais adequado para a cada situação. Para quem não sabe eu já escrevi um livro de JPA e ainda assim não o considero a bala de prata para todos os problemas.

Espero que vocês gostem. [=

JPA Hibernate Alternatives. What can I use if JPA or Hibernate is not good enough for my project?

15

Posted on by

Share it now!

Hello, how are you?

Today we will talk about situations that the use of the JPA/Hibernate is not recommended. Which alternatives do we have outside the JPA world?

What we will talk about:

  • JPA/Hibernate problems

  • Solutions to some of the JPA/Hibernate problems

  • Criteria for choosing the frameworks described here

  • Spring JDBC Template

  • MyBatis

  • Sormula

  • sql2o

  • Take a look at: jOOQ and Avaje

  • Is a raw JDBC approach worth it?

  • How can I choose the right framework?

  • Final thoughts

I have created 4 CRUDs in my github using the frameworks mentioned in this post, you will find the URL at the beginning of each page.

I am not a radical that thinks that JPA is worthless, but I do believe that we need to choose the right framework for the each situation. If you do not know I wrote a JPA book (in Portuguese only) and I do not think that JPA is the silver bullet that will solve all the problems.

I hope you like the post. [=

Ultimo dia da promoção compre 1 e leve outro da Packt

2

Posted on by

Share it now!

Pessoal, bom dia.

Entraram em contato comigo da editora Pack pedindo para anunciar o último dia da promoção:

Packt Publishing celebrates their 2000th title with an exclusive offer – We’ve got IT covered!

Abaixo o texto promocional:

Known for their extensive range of pragmatic IT ebooks, Packt Publishing are celebrating their 2000th book title `Learning Dart’– they want their customers to celebrate too.

To mark this milestone Packt Publishing will launch a ‘Buy One Get One Free’ offer across all eBooks on March 18th – for a limited period only.

Packt is one of the most prolific and fast-growing tech book publishers in the world. Originally focused on open source software, Packt contributes back into the community paying a royalty on relevant books directly to open source projects. These projects have received over $400,000 as part of Packt’s Open Source Royalty Scheme to date.

Their books focus on practicality, recognising that readers are ultimately concerned with getting the job done. Packt’s digitally-focused business model allows them to quickly publish up-to-date books in very specific areas across a range of key categories – web development, game development, big data, application development, and more. Their commitment to providing a comprehensive range of titles has seen Packt publish 1054% more titles in 2013 than in 2006.

Here are some of the best titles across Packt’s main categories – but Buy One, Get One Free will apply across all 2000 titles:

Last day to by one and get other book for free!

0

Posted on by

Share it now!

Hello, how are you?

The people from Packt Publishing asked me to announce:

 

Packt Publishing celebrates their 2000th title with an exclusive offer – We’ve got IT covered!

Known for their extensive range of pragmatic IT ebooks, Packt Publishing are celebrating their 2000th book title `Learning Dart’– they want their customers to celebrate too.

To mark this milestone Packt Publishing will launch a ‘Buy One Get One Free’ offer across all eBooks on March 18th – for a limited period only.

Packt is one of the most prolific and fast-growing tech book publishers in the world. Originally focused on open source software, Packt contributes back into the community paying a royalty on relevant books directly to open source projects. These projects have received over $400,000 as part of Packt’s Open Source Royalty Scheme to date.

Their books focus on practicality, recognising that readers are ultimately concerned with getting the job done. Packt’s digitally-focused business model allows them to quickly publish up-to-date books in very specific areas across a range of key categories – web development, game development, big data, application development, and more. Their commitment to providing a comprehensive range of titles has seen Packt publish 1054% more titles in 2013 than in 2006.

Here are some of the best titles across Packt’s main categories – but Buy One, Get One Free will apply across all 2000 titles:

1 2 3 4 5 13 14