# Anotações para o Modelo

## Anotações para o Modelo

Como mencionado anteriormente, o Artemis é orientado a anotações para que facilite a vida do desenvolvedor Java. Essas anotações têm algumas categorias:

* Anotação para modelo
* Anotação para qualificação

### Anotações para o Modelo

As anotações para o Modelo tem como objetivo transformar o modelo, orientado a objetos, para a camada de comunicação, Diana. Para mapeamento do modelo existe:

* Entity
* Column
* MappedSuperclass
* Id
* SubEntity
* Embeddable
* Convert

O JNoSQL Artemis não requer métodos getter e setter para os campos, no entanto, as classes do tipo entidade precisam ter um construtor padrão ou protegido por pacote.

#### Entity

Essa anotação tem como objetivo mapear a classe que será utilizada como entidade dentro do Artemis, ela possui um único atributo: name. Esse atributo tem como objetivo informar o nome da Família de coluna, Coleção de documentos, chave valor, etc. Caso ele não seja informado será utilizado o nome simples da classe, por exemplo, a Classe org.jnosql.demo.Person ele usará o Person como nome.

```java
@Entity
public class Person {
}
```

```java
@Entity("name")
public class Person {
}
```

#### Column

Essa anotação observada os atributos dentro da classe, anotada com Entity.

```java
@Entity
public class Person {
    @Column
    private String nickname;
    @Column
    private String name;
    @Column
    private List<String> phones;
    //ignored
    private String address;
//getter and setter
}
```

#### MappedSuperclass

Faz com que o Artemis olhe para os atributos da classe pai, cujo os atributos sejam anotados com Column,

```java
@Entity
public class Dog extends Animal {

    @Column
    private String name;
    //getter and setter

}

@MappedSuperclass
public class Animal {

    @Column
    private String race;

    @Column
    private Integer age;

    //getter and setter

}
```

No exemplo citado, ao salvar a classe `Dog` será levado em consideração também os campos da classe `Animal`, ou seja, serão persistidos três campos, `name`, `race` e `age`.

#### Id

Ele indica qual dos atributos é o id, ou a chave para banco de dados do tipo chave-valor. A forma de armazenamento da classe vai depender do driver do banco de dados.

```java
@Entity
public class User implements Serializable {

    @Id
    private String userName;

    private String name;

    private List<String> phones;

        }
```

#### Embeddable

Indica que as classes com essa anotação serão persistidas de forma embarcada, ou seja, na conversão de uma entidade para o tipo documentos o tipo embarcado será um suddocumento.

```java
@Entity
public class Book {

    @Column
    private String name;

    @Column
    private Author author;

//getter and setter

}

@Embeddable
public class Author {

    @Column
    private String name;

    @Column
    private Integer age;

//getter and setter

}
```

#### SubEntity

Indica que as classes com essa anotação serão persistidas de forma integrada a entidade principal, como parte direta da mesma, assim uma sub entidade.

```java
@Entity
public class Book {

    @Column
    private String name;

    @Column
    private Author author;

//getter and setter

}

@SubEntity
public class Author {

    @Column
    private String name;

    @Column
    private Integer age;

//getter and setter

}
```

#### Convert

Assim como o Diana, o Artemis também possui o recurso para realizar conversão de tipos. Esse tipo de recurso é interessante também para, por exemplo, criptografar uma informação texto, de String para String. Como parâmetro essa anotação precisa de uma classe que implemente AttributeConverter. No exemplo abaixo, foi criado a classe salário com um converter para a classe criada Money.

```java
@Entity
public class Worker {
    @Column
    private String name;
    @Column
    private Job job;
    @Column("money")
    @Convert(MoneyConverter.class)
    private Money salary;
//getter and setter
}

public class MoneyConverter implements AttributeConverter<Money, String>{
    @Override
    public String convertToDatabaseColumn(Money attribute) {
        return attribute.toString();
    }
    @Override
    public Money convertToEntityAttribute(String dbData) {
        return Money.parse(dbData);
    }
}
public class Money {
    private final String currency;

    private final BigDecimal value;

//....
}
```

## Anotação para qualificação

Em alguns momentos é necessário trabalhar com o mesmo tipo de banco de dados, por exemplo, trabalhar com dois bancos do tipo documentos.

```java
@Inject
private DocumentRepository repositoryA;
@Inject
private DocumentRepository repositoryB;
```

Como nos dois casos ele implementa a mesma interface será retornado em tempo de execução pelo CDI um problema de ambiguidade de injeção. Para resolver esse problema existe o qualificador que a API já traz, o qualificador `Database`. Essa API possui dois atributos:

* **DatabaseType**: O tipo de banco de dados, por exemplo, chave-valor documentos, grafo ou família de coluna
* **provider**: O nome do provedor do banco de dados, por exemplo, “cassandra”, “hbase”, “mongoDB”, etc. Assim, para resolver o problema mencionado anteriormente existe é necessário anotar com o qualificador.

```java
@Inject
@Database(value = DatabaseType.DOCUMENT, provider = “databaseA”)
private DocumentRepository repositoryA;
@Inject
@Database(value = DatabaseType.DOCUMENT, provider = “databaseB”)
private DocumentRepository repositoryB;
```

Obviamente será necessário a criação de métodos produtores com os mesmos qualificadores que falaremos mais a frente.

Um ponto importante é da integração do Artemis com esse qualificador. Caso ele seja utilizado para a criação dos Entity Manager do Diana (ColumnFamilyManager, DocumentCollectionManager, BucketManager, etc.) o Artemis gerenciará todo o ciclo de vida de classes como DocumentRepository, ColumnRepository, dentro outros que será visto mais a frente.

## ConfigurationUnit

Armazenar as configurações do banco de dados como senha e usuário é algo muito importante para uma aplicação. O Eclipse JNoSQL Artemis tem a anotação ConfigurationUnit, ela lê a configuração a partir de arquivos como XML e JSON e o injeta criando uma fábrica. Esse arquivo de configuração pode estar na parta **META-INF** ou **WEB-INF**

### Estrutura de um arquivo JSON

```javascript
[
   {
      "description":"that is the description",
      "name":"name",
      "provider":"class",
      "settings":{
         "key":"value"
      }
   },
   {
      "description":"that is the description",
      "name":"name-2",
      "provider":"class",
      "settings":{
         "key":"value"
      }
   }
]
```

### Estrutura de um arquivo XML

```markup
<?xml version="1.0" encoding="UTF-8"?>
<configurations>
   <configuration>
      <description>that is the description</description>
      <name>name</name>
      <provider>class</provider>
      <settings>
         <entry>
            <key>key2</key>
            <value>value2</value>
         </entry>
         <entry>
            <key>key</key>
            <value>value</value>
         </entry>
      </settings>
   </configuration>
</configurations>
```

### Injection the code

Com o arquivo de configuração, o próximo passo é o injetar na aplicação, o Eclipse JNoSQL Artemis, por padrão, tem suporte para as seguintes classes:

* BucketManagerFactory
* DocumentCollectionManagerAsyncFactory
* DocumentCollectionManagerAsyncFactory
* ColumnFamilyManagerAsyncFactory
* ColumnFamilyManagerAsyncFactory

```java
    @Inject
    @ConfigurationUnit(fileName = "column.xml", name = "name")
    private ColumnFamilyManagerFactory<?> factoryA;

    @Inject
    @ConfigurationUnit(fileName = "document.json", name = "name-2")
    private DocumentCollectionManagerFactory factoryB;

    @Inject
    @ConfigurationUnit
    private BucketManagerFactory factoryB;
```

### Dependência do ConfigurationUnit

Para utilizar a anotação o seu comportamento padrão de ConfigurationUnit, é necessário adicionar a dependência de configuração.

```markup
   <dependency>
        <groupId>org.jnosql.artemis</groupId>
        <artifactId>artemis-configuration</artifactId>
        <version>0.0.4-SNAPSHOT</version>
    </<dependency>
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jnosql.gitbook.io/jnosql-book/pt-br/part4/chapter4_1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
