How to handle @Lob properties when using 2 different databases with Hibernate


#1

We have a legacy application using Derby that we want to now work with both PostgreSQL and Derby.
Everything works fine on both except for this CLOB handling that needs to be different for this one class…
Switching the annotations as follows works, but we want one build for either DB.

For Derby

@MappedSuperclass
public class AbstractXmlLobBean extends StandardRootBean {
	@Lob
	@Column(name = "marshalledXml")
	private String xml;

For PostgreSQL (we need it to use ‘text’)

@MappedSuperclass
public class AbstractXmlLobBean extends StandardRootBean {
	@Lob
	@Type(type = "org.hibernate.type.TextType")
	@Column(name = "marshalledXml")
	private String xml;

How can we accomplish this (using either annotations / mapping files / programatically)?

This is using Hibernate 3.6.9.
Thanks!


#2

So how do the @Lob handling differs between the two?


#3

For Postgres, I need to have:

@Type(type = "org.hibernate.type.TextType")

In order for it to use ‘text’ in the database.

But I can NOT have that annotation for Derby otherwise the LOBs will not work.


#4

You can use the annotation by default, and override the mapping using XML for Derby.

Check out this article for more details.


#5

Thanks, I’m trying but not sure how to do the xml.

Should I be using entity-mappings like in the page you sent? If so, how do I register those into hibernate config?

Or should I be using hibernate-mapping in which case I’m not sure what the xml should look like.

Our hibernate configuration code looks like this… (trying to add the xml resource)

	protected Configuration createHibernateConfiguration() {
		final Configuration cfg = new Configuration();
		cfg.configure(this.tasDbConfig.getHibernateConfigResource());

		// Entities
		for (Class<?> aClass : getEntityClasses()) {
			cfg.addAnnotatedClass(aClass);
		}
		if( this.tasDbConfig.getDbType() == DefaultTASDBConfig.DatabaseType.Derby ) {
			cfg.addResource("AbstractXMLLobBean-derby.hbm.xml");
		}
		cfg.setInterceptor(new MyInterceptor());
		return cfg;
	}

#6

You can use the Hibernate legacy mapping too.


#7

So what would the XML (Hibernate 3.6.9) look like to be the equivalent of these annotations?

@MappedSuperclass
public class AbstractXmlLobBean extends StandardRootBean {
	@Lob
	@Column(name = "marshalledXml")
	private String xml;

#8

There wouldn’t be any equivalent in HBM for MappedSuperclass. You can use the Hibernate 3 documentation to find what was available back then. HBM mappings are deprecated anyway, so you are better off migrating to Hibernate 5 in the long run.


#9

Migrating to Hibernate 5 is sort of out of the question. Like I said, this is an existing legacy app that needs to run on Postgres (cause it outgrew Derby on one install).

If I were to use the entity-mappings like you suggest, how do I register that xml mapping into the Hibernate configuration?


#10

You can use the addResource method of the Configuration object.

However, you need to pass the relative path of the XML file as it’s located on the classptah. To see how that works, just add a breakpoint in this Hibernate test and run the test in debug mode.