11

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?

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
keddok
  • 531
  • 1
  • 5
  • 15

3 Answers3

10

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.

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
  • Nice, `@Table` annotation works too! Hope this is a stable feature. – keddok Oct 31 '18 at 08:39
  • 1
    I don't see a reason why it shouldn't. It will probably see some extension and improvement (like a `name` attribute equivalent to the `value` attribute). – Jens Schauder Oct 31 '18 at 09:12
  • @JensSchauder Could you put an example as a new answer ? – Kartoch Nov 07 '18 at 08:25
  • 1
    @Kartoch Not sure, why I'd put an example in a separate answer, but I updated the answer with an example demonstrating the use of the `@Table` and `@Column` annotation. – Jens Schauder Nov 07 '18 at 08:52
5

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";
            }
        };
    }
}
Kartoch
  • 7,610
  • 9
  • 40
  • 68
  • Thanx, @Kartoch! Seems this approach is valid and i was able to go further. Unfortunately i stuck into other problem and can't verify completness of this solution. I'll keep you up to date. – keddok Oct 30 '18 at 14:07
  • 1
    UPDATE. Yes, `NamingStrategy` bean did his job well. – keddok Oct 31 '18 at 08:44
  • @keddok could you put an example as a new answer ? – Kartoch Nov 07 '18 at 08:26
  • pushed a simple boot application using `NamingStrategy` configuration for schema: https://github.com/keddok/sandbox/tree/master/spring-data-jdbc – keddok Nov 09 '18 at 07:45
-4

Use @Table(name = "metric_value").

Sai prateek
  • 11,842
  • 9
  • 51
  • 66
Ashoka
  • 26
  • 5