9
votes

In Spring Data JPA we can map an entity to a specific table by using @Table annotation where we can specify schema and name.

But Spring Data JDBC uses a NamingStrategy to map an entity to a table name by converting the entities class name. For example, if we have the entity class named MetricValue then the table should be named metricvalue in default schema. But I need to map MetricValue to the metric_value table in app schema.

Is there any way to override this mapping by annotation or any other?

3

3 Answers

4
votes

The naming behavior is defined by the default implementation of the interface NamingStrategy

From reference documentation, section 4.4.3 of version 1.0.2:

When you use the standard implementations of CrudRepository that Spring Data JDBC provides, they expect a certain table structure. You can tweak that by providing a NamingStrategy in your application context.

The default implementation has the following behavior (from javadoc version 1.0.2):

Defaults to no schema, table name based on Class and column name based on RelationalPersistentProperty with name parts of both separated by '_'.

So create a bean which implements NamingStrategy in register it in your application context.

This is an example from @keddok comment:

@Configuration
@EnableJdbcRepositories
public class MetricStoreRepositoryConfig extends JdbcConfiguration {
    @Autowired
    private DataSource dataSource;

    @Bean
    NamedParameterJdbcOperations operations() {
        return new NamedParameterJdbcTemplate(dataSource);
    }

    @Bean
    PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    NamingStrategy namingStrategy() {
        return new NamingStrategy() {
            @Override
            public String getSchema() {
                return "metric";
            }
        };
    }
}
8
votes

Spring Data JDBC has it's own @Table annotation and also an @Column one.

You just add the annotation to your entity and specify the name as the value of the annotation.

To give some examples:

@Table("entity") 
class MyEntity {

    private @Column("last_name") String name;

    @Column(value = "entity_id", keyColumn = "entity_index") 
    private List<SomeOtherEntity> someList;
}

This will read and write MyEntity into/from the table entity instead of the default my_entity. The attribute name will get stored in the column last_name. And the columns for backreferencing from the some_other_entity to entity will be named entity_id for the foreign key column which normally would be entity (the table name of the referenced table). And the list index will be stored in entity_index instead of the default entity_key.

I created an issue for improving the documentation.

-4
votes

Use @Table(name = "metric_value").