How do I configure JPA table name at runtime?

5.6k views Asked by At

I have an issue where I have only one database to use but I have multiple servers where I want them to use a different table name for each server.

Right now my class is configured as:

@Entity
@Table(name="loader_queue")
class LoaderQueue

I want to be able to have dev1 server point to loader_queue_dev1 table, and dev2 server point to loader_queue_dev2 table for instance.

Is there a way i can do this with or without using annotations?

I want to be able to have one single build and then at runtime use something like a system property to change that table name.

2

There are 2 answers

3
Vlad Mihalcea On BEST ANSWER

For Hibernate 4.x, you can use a custom naming strategy that generates the table name dynamically at runtime. The server name could be provided by a system property and so your strategy could look like this:

public class ServerAwareNamingStrategy extends ImprovedNamingStrategy {

    @Override
    public String classToTableName(String className) {
        String tableName = super.classToTableName(className);
        return resolveServer(tableName);
    }

    private String resolveServer(String tableName) {
        StringBuilder tableNameBuilder = new StringBuilder();

        tableNameBuilder.append(tableName);
        tableNameBuilder.append("_");
        tableNameBuilder.append(System.getProperty("SERVER_NAME"));

        return tableNameBuilder.toString();
    }
}

And supply the naming strategy as a Hibernate configuration property:

<property 
    name="hibernate.ejb.naming_strategy" 
    value="my.package.ServerAwareNamingStrategy"
/>
2
Jens Schauder On

I would not do this. It is very much against the grain of JPA and very likely to cause problems down the road. I'd rather add a layer of views to the tables providing unified names to be used by your application.

But you asked, so have some ideas how it might work:

  1. You might be able to create the mapping for your classes, completely by code. This is likely to be tedious, but gives you full flexibility.

  2. You can implement a NamingStrategy which translates your class name to table names, and depends on the instance it is running on.

  3. You can change your code during the build process to build two (or more) artefacts from one source.