1

I know there are few threads about this, but I cannot understand why it is not working with my code. I have the entire database with capital letters, columns, table names, sequences.But when I try to make a query, via sql or criteria, It transforms all values in lowercase. I found a workaround but I don't want to write queries like:

select a."COLUMN_1", a."COLUMN_2" from schema."A" a 

And mappings like:

@Entity(name = "`A`")
public class A implements Serializable {
     @Column(name = "`COLUMN_1`")
     private Integer column1;
     @Column(name = "`COLUMN_2`")
     private Integer column2;

}

I tried to follow some threads in stackoverflow implementing my own naming strategy, but it neither didn't work .

public class ModifiedImprovedNamingStrategy extends PhysicalNamingStrategyStandardImpl{

    @Override
    public final Identifier toPhysicalColumnName(final Identifier name, final JdbcEnvironment context) {
        return new Identifier(addUnderscores(name.getText()), name.isQuoted());
    }

    /**
     * Adds the underscores.
     *
     * @param name
     *            the name
     * @return the string
     */
    protected static String addUnderscores(final String name) {
        final StringBuilder buf = new StringBuilder(name.replace('.', '_'));
        for (int i = 1; i < (buf.length() - 1); i++) {
            if (Character.isLowerCase(buf.charAt(i - 1))
                    && Character.isUpperCase(buf.charAt(i))
                    && Character.isLowerCase(buf.charAt(i + 1))) {
                buf.insert(i++, '_');
            }
        }
        return "`" + buf.toString().toUpperCase(Locale.ROOT) + "`";
    }
  }

And then calling it in my applicationContext like that:

<bean id="sessionFactory"
        class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"
        p:dataSource-ref="dataSource">
        <property name="packagesToScan" value="com.services.vo"/>
        <property name="mappingLocations">
            <list>
                <value>classpath*:hibernate/queries/**.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.transaction.coordinator_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
                <prop key="hibernate.physical_naming_strategy">com.services.util.hibernate.ModifiedImprovedNamingStrategy</prop>
                <prop key="hibernate.format_sql">true</prop>
            </props>
        </property>
    </bean>

My intention is to avoid writing those everywhere. I tried to set a breakpoint inside the overrided ModifiedImprovedNamingStrategy methods. When I try a unit test, but it is not stopping there.Is there any way to do what I want? or will I be forced to keep those ?

Thanks in advance

Hema
  • 988
  • 1
  • 16
  • 38
txomin
  • 177
  • 2
  • 3
  • 15
  • Related: https://stackoverflow.com/questions/32437202/improvednamingstrategy-no-longer-working-in-hibernate-5 –  May 24 '17 at 05:41
  • Those backticks are invalid for Postgres identifiers to begin with –  May 24 '17 at 05:51
  • 1
    "*I have the entire database with capital letters*" - why did you do that? The best thing to do, is to never use double quotes for identifiers. Neither when creating them (which defines how you need to access those names later). –  May 24 '17 at 05:53
  • @RC, if you see my code, you'll notice that i do the same implementation as the guy recommends in that thread... so i guess the solution is to change all database table and column names, isnt it @a_horse_with_no_name? i didn't know about this issue before now... that's why i put everything in uppercase. – txomin May 24 '17 at 06:35
  • @txomin that's why I "linked" to the question –  May 24 '17 at 07:51
  • After trying few more things i desist, so, @a_horse_with_no_name if you post the answer i can mark it as the correct one!!! thanks – txomin May 24 '17 at 08:56

1 Answers1

0

I believe you have to add annotation @Table(name = "A") in your case to mapping your Entity A into database table A , Here's my how i use it, hope it helps:

@Entity
@Table(name = "house")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Document(indexName = "house")
public class House implements Serializable {
    @NotNull
    @Column(name = "location", nullable = false)
    private String location;

    @Size(max = 200)
    @Column(name = "description", length = 200)
    private String description;
}
Haifeng Zhang
  • 30,077
  • 19
  • 81
  • 125
  • 1
    that's not working, when a query is lanched it appears an error saying that "a table does not exist" – txomin May 24 '17 at 06:29