I would like to rename a PostgreSQL (9.6) table in a way that is recoverable for my system (A java app using JPA/Hibernate)
In my java code, a JPA entity would have the following annotations @Entity
@Table(name="old_name")
and the database would have an equivalent table called old_name
.
I would like to rename the table to new_name
in a way that I can incrementally update the database and java app, allowing for failure and rollback.
Typical steps would be
- create copy of
old_name
innew_name
- ensure read/writes available in both (i.e. data is replicated both ways)
- update java app to use new table
new_name
- when confident system update complete, remove
old_name
Effectively I would like a duplicate table in the same schema with the same data, both able to accept reads and writes, that can be read from JPA entities.
I am aware of the use of triggers, and would like to avoid that. I am hoping there is a technique I'm not aware of and haven't found that would make this less painful than using triggers.
I have tried to rename the table and create a "simple view" over it, however the JPA entity complains as it can't find a table with the name of the view. (Because it is a view, not a table :) and there seems no @View/@Table JPA annotation that will handle this)
I haven't yet tried the facilities listed here: http://wiki.postgresql.org/wiki/Replication,_Clustering,_and_Connection_Pooling as the majority seem to be about pooling, sharding, and I need a simple short term table replica, but I will be investigating these also.
Thanks - I would like the simplest option of course, preferring something built in to postgres/JPA but will seriously consider 3rd party options also.
Database tables
Assuming you have the following two tables:
JPA entity
The
old_post
table must be replicated with the newerpost
. Notice that thepost
table has more columns now than the old table.We only need to map the
Post
entity:Hibernate event listeners
Now, we have to register 3 event listeners to intercept the INSERT, UPDATE, and DELETE operations for the
Post
entity.We can do this via the following event listeners:
The 3 event listeners can be registered using a Hibernate
Integrator
:And, to instruct Hibernate to use this custom
Integrator
, you need to set up thehibernate.integrator_provider
configuration property:Testing time
Now, when persisting a
Post
entity:Hibernate will execute the following SQL INSERT statements:
When doing another transaction that updates an existing
Post
entity and creates a newPost
entity:Hibernate replicates all actions to the
old_post
table as well:When deleting a
Post
entity:The
old_post
record is deletected as well:For more details, check out this article.
Code available on GitHub.