41

I am developing a project in which I am persisting some POJOs by adding Hibernate annotations. One problem I am running into is that code like this fails, as Hibernate tries to map the sub-fields within the Time_T onto the same column (i.e. startTime.sec and stopTime.sec both try to map to the colum sec, causing an error).

@Entity
public class ExampleClass
{
  @Id
  long eventId;

  Time_T startTime;
  Time_T stopTime;
}

@Embeddable
public class Time_T
{
  int sec;
  int nsec;
}

As there will be many occurrences like this throughout the system, it would be nice if there was an option to automatically append a prefix to the column name (e.g. make the columns be startTime_sec, startTime_nsec, stopTime_sec, stopTime_nsec), without having to apply overrides on a per-field basis. Does Hibernate have this capability, or is there any other reasonable work-around?

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
VeeArr
  • 6,039
  • 3
  • 24
  • 45

4 Answers4

32

Try setting the property hibernate.ejb.naming_strategy to org.hibernate.cfg.DefaultComponentSafeNamingStrategy

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 14
    Hibernate 5 split the naming strategy in an implicit part (when no explicit column overrides are given) and an physical part, which overrides any naming even when explicitly defined with column annotations. There is a default implicit naming strategy available, which prefixes embedded classes: `hibernate.implicit_naming_strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl` See also the [hibernate documentation][1] for more details [1]: https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/chapters/domain/naming.html – Arjan Mels Mar 27 '17 at 17:58
  • 2
    What if I am already using a custom naming strategy? Is there a specific method to override with a method from this strategy? – Mattias Martens Jan 31 '18 at 20:05
  • @MattiasMartens you can do this by providing your implementation and configuring it instead. I had to do this in the context of Spring Boot which uses `SpringImplicitNamingStrategy` by default. This prevented me to switch to `ImplicitNamingStrategyComponentPathImpl` which i then sub classed and overrode `public Identifier determineJoinTableName(ImplicitJoinTableNameSource source)` with spring boot's impl. – elonderin May 13 '21 at 09:41
15

In my case with org.hibernate:hibernate-core:5.0.12.Final and org.springframework.boot:spring-boot-starter-data-jpa:1.5.2.RELEASE I had to do the following properties in my application.properties file:

spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
Farrukh Najmi
  • 5,055
  • 3
  • 35
  • 54
  • 3
    im using spring boot 2.5.4, only `spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl` is enough if you want to retain _ instead of camel-case – keemahs Sep 03 '21 at 02:24
7

Another way to solve the problem is by using @AttributeOverrides and @AttributeOverride annotations. In your example the Time_T.sec property is mapped to sec column. You could map ExampleClass like this:

@Entity
public class ExampleClass {
    @Id
    long eventId;

    @AttributeOverrides(
        @AttributeOverride(name = "sec", column = @Column(name = "start_sec"))
    )
    Time_T startTime;
    Time_T stopTime;
}

The result mapping is startTime.sec <=> start_sec and stopTime.sec <=> sec. Of course you could use annotations to create a more meaningful name for stopTipe.sec column.

Matheus Moreira
  • 2,338
  • 4
  • 24
  • 31
  • 5
    This is explicitly what I don't want to do, as there could be many instances of this pattern throughout the code. I would not want to add in the `@AttributeOverrides` annotations several hundred times. – VeeArr Jun 15 '10 at 16:32
  • 2
    I'm sorry, I didn't pay enough attention to your first message. You clearly stated that you didn't want to manually override the fields. – Matheus Moreira Jun 24 '10 at 01:15
-2

spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl