Se você for definir uma tabela, por favor, não faça isso!
Vamos saber melhor por que!
No JPA, uma classe é mapeada para uma tabela através da anotação @Entity
. Com essa anotação nós indicamos que a classe é uma entidade do JPA, nesse caso, automaticamente ele mapeia a classe para uma tabela.
Para isso, o JPA está configurado por default a resolver o nome da classe para uma tabela da seguinte forma:
1 - Classes no Java são definidas através de PascalCase.
2 - O nome da classe é convertida em snake_case.
3 - Este nome convertido é utilizado para o nome da tabela no banco de dados.
Então, através desse algoritmo:
CustomerDetails -> customer_details
No caso do exemplo original:
Product -> product
Só isso já conseguimos eliminar a necessidade da anotação @Table
.
Conseguimos também definir o nome da tabela ao definir o nome da entidade nas queries JPQL. Isso porque o nome da tabela é resolvido através do seu nome nas queries. Primeiro, por default, é resolvido pelo nome da classe da entidade, porém podemos mudar esse nome pela anotação @Entity
:
@Entity(name = "blablabla")
Só fazendo isso, conseguimos mudar o nome da tabela que será mapeada e de quebra também o nome que iremos utilizar para as queries JPQL.
Podemos ter edge cases para definir as duas anotações, que é quando a tabela tem um nome específico, e nas queries JPQL iremos nos referir ao nome da classe mesmo, exemplo:
@Entity
@Table(name="products")
public class Product {
}
No caso aqui, o nome da tabela está no plural, porém na query JPQL, iremos utilizar o nome da classe mesmo:
@Query("Product p where p.vendorId = :vendorId")
Product findProductFromVendor(int vendorId);
Neste caso, a query que isso irá gera no SQL será o seguinte:
SELECT * FROM products WHERE vendor_id = 10
Outro edge case seria se eu quisesse que o nome da entidade nas queries seja diferente do nome da classe e o nome na tabela seja diferente dos dois:
@Entity(name="prod")
@Table(name="products")
public class Product{
}
É essencial entender o funcionamento das anotações e do framework que estamos utilizando para não cairmos em redundância desnecessária na hora de programar!
Top comments (1)
Oi, Eron. Vc se confundiu ao descrever o comportamento padrão do JPA.
O JPA, por padrão mapea para tabelas no banco de dados com o mesmo nome da entidade.
O exemplo abaixo mapeará para uma tabela chamada
CustomerDetails
, pois o nome da entidade, por padrão, é o unqualified name da classe, e não "customer_details" como vc disse.O que vc descreveu como sendo o comportamento padrão do JPA, na verdade é o comportamento oferecido pela
PhysicalNamingStrategy
CamelCaseToUnderscoresNamingStrategy
do Hibernate e que é o padrão em aplicações que usam Spring Boot.Anotar
Product
com@Table(name = "product")
não é bem uma redundância desnecessária, já que ela assegura que o nome da tabela esteja como esperado independente daPhysicalNamingStrategy
utilizada em caso de uma mudança brusca no Spring Boot ou mesmo de uma migração para outro framework.Além disso, eu não diria que seu exemplo com
@Table(name="products")
é um edge case já que é extremamente comum encontrar tableas nomeadas no plural ou mesmo com prefixos como "tbl_".