简体   繁体   中英

Grails GORM database mapping for unidirectional 1:n relationship

I am currently trying to create a new Grails application based on a legacy MySQL database. The application should only read information. The concrete DB schema uses for the specific domain classes a table per class hierarchy structure, as well as a property class to add new needed information to these classes.

Currently I cannot retrieve the property information for a transation . There is no exception, but I also cannot access the field properties . One problem I may face is, that the word properties is a keyword for Grails for the domain fields. But I need to use it because of the specific legacy table naming.

The legacy tables are named transaction and transaction_properties . One transcation can have muliple transaction_properties . The association is done via the key transaction_id in the transaction_properties table.

Table transaction

id  bigint(20)
transaction_id  varchar(255) (bad naming here, transaction_id is used to store additional meta information)

Table transaction_properties

transaction_id  bigint(20) -> referencing to transation.id
property_value  varchar(255)
property_key    varchar(32)
etc.

Domain class Transaction

class Transaction {

static hasMany = [properties : TransactionProperty]

static constraints = {
    //   transactionProperty unique: true
}

static mapping = {
    table "transaction"
    version false
    columns {
        id column : "id"
        beginDate column : "start"
        endDate column : "end"
        type column : "DTYPE"
        amount column : "total_amount"
        metaId column : "transaction_id"
        purchase column : "purchase_id"
        service column : "service_id"
        origin column : "origin_id"
        properties column : "id"
    }

}

Long id
Date beginDate
Date endDate
String type
String amount
String metaId

Purchase purchase
Origin origin
Service service
  etc.
  }

Domain class TransactionProperty

  class TransactionProperty {

static mapping = {
    table "transaction_properties"
    version false
    columns {
        id name : "transaction_id"
        key column : "property_key"
        value column : "property_value"
    }
}

String value
String key
Long id

def asString(){
    return "${key} = ${value}"
}
   }

Your code is a giant mess.

You need to add a static belongsTo = [transaction: Transaction] in your TransactionProperty domain class. This will tell grails to use the foreign key in that table instead of wanting a join table.

You also do not need to specify Long id in either table. That is done by default in Grails.

Remove these column mappings as well in the Transaction domain class:

id column : "id"
properties column : "id"

In TransactionProperty, it technically does not have a primary key (unless you are hiding it from us), so you will have to use a composite key of property_key and property_value.

id name : "transaction_id"

should be:

id composite: ['key', 'value']

Read up on the additional requirements of this here: http://grails.org/doc/latest/guide/GORM.html#5.5.2.5%20Composite%20Primary%20Keys

My best attempt at fixing your classes:

Transaction:

class Transaction {

static hasMany = [properties : TransactionProperty]

static constraints = {
}

static mapping = {
    table "transaction"
    version false
    columns {
        beginDate column : "start"
        endDate column : "end"
        type column : "DTYPE"
        amount column : "total_amount"
        metaId column : "transaction_id"
        purchase column : "purchase_id"
        service column : "service_id"
        origin column : "origin_id"
    }

}

Date beginDate
Date endDate
String type
String amount
String metaId

Purchase purchase
Origin origin
Service service

}

TransactionProperty:

import org.apache.commons.lang.builder.HashCodeBuilder

class TransactionProperty implements Serializable {

static belongsTo = [transaction: Transaction]

static mapping = {
    table "transaction_properties"
    version false
    columns {
        key column : "property_key"
        value column : "property_value"
    }
}

String value
String key


def toString(){
    return "${key} = ${value}"
}

boolean equals(other) {
    if (!(other instanceof TransactionProperty)) {
        return false
    }

    other.key == key && other.value == value
}

int hashCode() {
    def builder = new HashCodeBuilder()
    builder.append key
    builder.append value
    builder.toHashCode()
}
}

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