使用Hibernate持久化java.util.Properties?

5

如何持久化一个包含java.util.Properties对象的对象?

需要注意的是,java.util.Properties对象不仅可以在自身中查找属性,还可以在默认属性列表中查找属性。默认属性列表本身就是另一个Properties对象,因此它也可以有另一个默认属性列表。查找单个属性可能要遍历多个Properties对象,直到找到该属性。

我正在构建的应用程序需要以类似Properties的层次结构提供可覆盖的属性,因此我想使用Properties而不是实现自己的数据结构。但是我不确定如何持久化它们。

  • 我需要创建一个自定义的UserType吗?有关此情况的操作指南吗?
  • 是否有任何教程或其他资源可以演示如何在Hibernate中持久化Properties?
2个回答

4

不确定这是否是一个“易如反掌”的事情,但由于您可以将Properties实例中的XML存储并从XML加载实例,因此您可以在实体上拥有一个@Lob属性来保存将被持久化的XML。

类似于:

 class MyEntity implements Serializable {
   @Transient
   Properties props;

   @Lob
   byte[] xmlProp; //the xml as a byte[]

   //ids, getters & setters ommited

 }

然后您可以实现一个DAO来完成持久化和检索实体的艰巨工作:

 class MyEntityDAO {

   public void persist(MyEntity entity){

    try {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        entity.getProps().storeToXML(bos, "a simple comment if you like");

        byte[] byteStream = bos.toByteArray();
                entity.setXmlProp = byteStream;

                //save your instance with hibernate...

    } catch (IOException e) {
        e.printStackTrace();
    }
   }

   public MyEntity retrieveById(Long id){

      Properties propFromDB = new Properties();

      MyEntity ent = //retrieve the instance with hibernate...

      try{
        Properties propFromDB = new Properties();
        ByteArrayInputStream bais = new ByteArrayInputStream(ent.getXmlProp());
        propFromDB.load(bais);
        ent.setProp(propFromDB);
        return ent;
      } catch (IOException ioe){
       ioe.printStackTrace();
      }
      return null;
   }
 }

请查看java.util.Properties API中的storeToXML和loadFromXML方法。希望这能有所帮助。

非常有趣的Lucas。我对这种方法唯一的问题是,我将无法根据属性中的键/值对进行搜索。你知道有什么解决办法吗? - Jason Nichols
基本上,您可以将xmlProp从byte []切换为String,使用ByteArray的内容填充String,并将xml本身持久化在该属性上。这将使您有可能查询数据,但看起来有点不正规。您要运行什么样的查询? - Lucas de Oliveira

3
第一个问题是:你需要存储层次结构元数据,还是只想存储所有属性。如果是后者,则仅需将所有属性(使用getPropertyNames())添加到Map中并保存它(保存映射几乎是微不足道的)。
如果要保留层次结构,则需要问的问题是-应该如何在数据库中表示此层次结构。
我能想象的最简单的方法是拥有一个表,其中包含以下列:
id | key | value | properties_set_id | parent_properties_set_id

但如何做到这一点 - 我无法立即想到。也许可以坚持使用 Set<PropertyEntry>

Bozho,我假设您会使Properties实例瞬态,但是在什么时候将属性导出到映射中呢?我不确定何时进行此操作的机制。 - Jason Nichols
@Jason Nichols 我的意思是手动处理。或者可能是一个 @PreX 事件监听器。也许可以通过 UserType 实现,但我从未编写过这样的代码,所以无法确定。 - Bozho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接