简体   繁体   中英

Grails, property names in embedded object in domain class causing problems

I'm using grails 2.3.4 and I have a domain class that embeds an object. The embedded object has a property called 'version' and it seems that this is conflicting with the 'version'-field automatically added to the database-table by GORM. The result is that the 'version'-field belonging to my embedded object isn't created in the database and as a consequence my application doesn't work properly.

My code looks like this:

class Thing {
  String someText
  EmbeddedThing embeddedThing
  Date someDate

  static embedded = ['embeddedThing']

  static constraints = {
    embeddedThing(unique: true)
  }
}

class EmbeddedThing {
  String textOfSomeSort
  String version
  String textOfSomeOtherSort
}

You might think that a quick fix is to rename the 'version'-property of the embedded object but the class belongs to an included sub-project (ie a JAR-file) that I'm not allowed to touch since other projects use it. So the solution needs to be done completely within my domain class, or at least in a manner that doesn't change the class of the embedded object.

版本是一个特殊的列名称,您应该在EmbeddedThin类中重命名版本字段

I actually found a solution to this problem by using a Hibernate UserType to represent the EmbeddedThing-class. My code now looks like this and works perfectly:

Thing.groovy:

import EmbeddedThingUserType

class Thing {
  String someText
  EmbeddedThing embeddedThing
  Date someDate

  static embedded = ['embeddedThing']

  static mapping = {
    version false
    embeddedThing type: EmbeddedThingUserType, {
      column name: "embedded_thing_text"
      column name: "embedded_thing_version"
      column name: "embedded_thing_other_text"
    }
  }

  static constraints = {
    embeddedThing(unique: true)
  }
}

EmbeddedThing.groovy:

class EmbeddedThing {
  String textOfSomeSort
  String version
  String textOfSomeOtherSort
}

EmbeddedThingUserType.groovy:

class EmbeddedThingUserType implements UserType {
  int[] sqlTypes() {
    return [StringType.INSTANCE.sqlType(),
        StringType.INSTANCE.sqlType(),
        StringType.INSTANCE.sqlType()]
  }

  Class returnedClass() {
    return EmbeddedThing
  }

  public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner)
      throws HibernateException, SQLException {
    if (resultSet && names) {
      return new EmbeddedThing(
          textOfSomeSort: resultSet?.getString(names[0] ?: '_missing_textOfSomeSort_'),
          version: resultSet?.getString(names[1] ?: '_missing_version_'),
          textOfSomeOtherSort: resultSet?.getString(names[2] ?: '_missing_textOfSomeOtherSort_'))
    } else {
      return null
    }
  }

  public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index)
      throws HibernateException, SQLException {
    if (value != null) {
      preparedStatement.setString(index, value?.textOfSomeSort)
      preparedStatement.setString(index + 1, value?.version)
      preparedStatement.setString(index + 2, value?.textOfSomeOtherSort)
    } else {
      preparedStatement.setString(index, '_missing_textOfSomeSort_')
      preparedStatement.setString(index + 1, '_missing_version_')
      preparedStatement.setString(index + 2, '_missing_textOfSomeOtherSort_')
    }
  }

  @Override
  public boolean isMutable() {
    return false
  }

  @Override
  public boolean equals(Object x, Object y) throws HibernateException {
    return x.equals(y)
  }

  @Override
  public int hashCode(Object x) throws HibernateException {
    assert (x != null)
    return x.hashCode()
  }

  @Override
  public Object deepCopy(Object value) throws HibernateException {
    return value
  }

  @Override
  public Object replace(Object original, Object target, Object owner)
      throws HibernateException {
    return original
  }

  @Override
  public Serializable disassemble(Object value) throws HibernateException {
    return (Serializable) value
  }

  @Override
  public Object assemble(Serializable cached, Object owner)
      throws HibernateException {
    return cached
  }
}

Config.groovy:

grails.gorm.default.mapping = {
    'user-type'( type: EmbeddedThingUserType, class: EmbeddedThing)
}

请为“ EmbeddedThing”类在“静态映射”中尝试version false

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM