1

I am practicing/learning some Spring Boot + JPA application and keep running into issues when attempting to save to database table.

It seems JPA is auto generating table name, even though I have provided the @Table annotation.

I have a simple POJO , marked with @Entity

@Entity
@Table(name="SongList")
public class SongList {

    @Id
    private Integer id;
    private String album;
    private String artist;
    private String title;

//Getter and Setter Methods 
}

An Interface that extends JPA CrudRepository

import org.springframework.data.repository.CrudRepository;

public interface songRepo extends CrudRepository<SongList,Integer> {
}

A properties yml file that sets datasource properties

spring:
  datasource:
    driverClassName : com.mysql.cj.jdbc.Driver
    url :  jdbc:mysql://localhost:3306/Songdb
    username : root
    password : learning

jpa:
    hibernate.ddl-auto : update
    generate-ddl  : false
    show-sql : true

And finally Test class :

@SpringBootTest
@RunWith(SpringRunner.class)
class DataJpaApplicationTests {

    @Autowired
    ApplicationContext context;

    @Test
    void saveSongs() {

        songRepo repo = (songRepo) context.getBean(songRepo.class);

        SongList songs = new SongList();
        songs.setId(4);
        songs.setTitle("High Hopes");
        songs.setAlbum("Panic! At the Disco");

        repo.save(songs);

    }

}

Upon running the Test class , my test fails with error :

ERROR:
org.hibernate.exception.SQLGrammarException: could not extract ResultSet
Caused by: java.sql.SQLSyntaxErrorException: Table 'songdb.song_list' doesn't exist

My database table already exists. The database is called Songdb (not songdb) and table is SongList.

I am not sure where is the table name 'song_list' being injected and why my database name is 'songdb' instead of 'Songdb' as provided in the url.

What am I missing here ? Please help!

user1462617
  • 413
  • 1
  • 13
  • 23

1 Answers1

2

That is because you are using the default naming strategy provided by Spring boot. Hibernate maps field names using a physical strategy and an implicit strategy. Hibernate uses the Physical Naming Strategy to map our logical names to a SQL table and its columns. Spring Boot, provides defaults for both these strategies spring.jpa.hibernate.naming.physical-strategy defaults to org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy, and spring.jpa.hibernate.naming.implicit-strategy defaults to org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy

The default naming strategy for spring-boot will :

  • Replace dots with underscores
  • Change camel case to snake case
  • Lower-case table name

You can change it by setting the property like :

spring:
  jpa:
    hibernate:
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
        implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl

For you just changing the physical naming strategy will fix your issue. You could also use org.hibernate.cfg.EJB3NamingStrategy which will keep the table name as it is provided. Now that you know the cause for the issue , you can fix it ay way you like.

You could customize the physical naming strategy like you want incase you want more control. Read : Hibernate naming strategy changing table names

Ananthapadmanabhan
  • 5,706
  • 6
  • 22
  • 39