Использование Grails с устаревшей базой данных
Я столкнулся с проблемой использования Grails с устаревшей базой данных Oracle. У меня есть устаревшая таблица TARGETTYPES с текстовым столбцом первичного ключа TARGETTYPECODE:
CREATE TABLE "TMS"."TARGETTYPES"
( "TARGETTYPECODE" VARCHAR2(100) NOT NULL ENABLE,
"TARGETTYPEDESCR" VARCHAR2(255 CHAR),
"ACTIVE" CHAR(1) DEFAULT 'Y' NOT NULL ENABLE,
CONSTRAINT "TARGETTYPES_PK" PRIMARY KEY ("TARGETTYPECODE")
)
Я создал класс домена Grails:
package tmsconf
class Targettypes {
static transients = ['Targettypecode']
void setTargettypecode(String Targettypecode) {
id = Targettypecode
}
String getTargettypecode() {
return Targettypecode
}
String targettypedescr
String active
static mapping = {
table 'TARGETTYPES'
version false
columns {
id generator:'assigned', column:"TARGETTYPECODE", type:'text'
}
}
static constraints = {
id()
targettypecode(size: 1..100, blank: false)
targettypedescr(size: 0..255)
active(size: 1..1, blank: false)
id(nullable: true)
}
String toString() {
return "${targettypecode}"
}
}
Также я создал контроллер класса:
package tmsconf
class TargettypesController {
def scaffold = true
}
Приложение успешно запущено.
Когда я нажимаю на ссылку tmsconf.TargettypesController, у меня появляется ошибка в консоли:
Error 2012-10-10 10:55:37,243 [http-bio-8080-exec-9] ERROR util.JDBCExceptionReporter - ORA-00918: column ambiguously defined
| Error 2012-10-10 10:55:37,305 [http-bio-8080-exec-9] ERROR errors.GrailsExceptionResolver - SQLSyntaxErrorException occurred when processing request: [GET] /TMSConf/targettypes/list
ORA-00918: column ambiguously defined
. Stacktrace follows:
Message: ORA-00918: column ambiguously defined
Line | Method
->> 445 | processError in oracle.jdbc.driver.T4CTTIoer
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 396 | processError in ''
| 879 | processError . . . . in oracle.jdbc.driver.T4C8Oall
| 450 | receive in oracle.jdbc.driver.T4CTTIfun
| 192 | doRPC . . . . . . . in ''
| 531 | doOALL in oracle.jdbc.driver.T4C8Oall
| 207 | doOall8 . . . . . . in oracle.jdbc.driver.T4CPreparedStatement
| 884 | executeForDescribe in ''
| 1167 | executeMaybeDescribe in oracle.jdbc.driver.OracleStatement
| 1289 | doExecuteWithTimeout in ''
| 3584 | executeInternal . . in oracle.jdbc.driver.OraclePreparedStatement
| 3628 | executeQuery in ''
| 1493 | executeQuery . . . . in oracle.jdbc.driver.OraclePreparedStatementWrapper
| 96 | executeQuery in org.apache.commons.dbcp.DelegatingPreparedStatement
| 55 | <init> . . . . . . . in grails.orm.PagedResultList
| 15 | list in tmsconf.TargettypesController
| 186 | doFilter . . . . . . in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 1110 | runWorker . . . . . in java.util.concurrent.ThreadPoolExecutor
| 603 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . . . . . . in java.lang.Thread
Пожалуйста помогите, где я не прав
1 ответ
Это должно работать:
package tmsconf
class Targettypes {
String targettypecode
String targettypedescr
String active
static mapping = {
version false
id generator: 'assigned', name: 'targettypecode'
}
static constraints = {
targettypecode(size: 1..100, blank: false)
targettypedescr(size: 0..255, nullable: true)
active(size: 1..1, blank: false)
}
String toString() {
targettypecode
}
}
Теперь вы можете использовать name
недвижимость в mapping
блок, поэтому создание переходной пары get / set для переноса идентификатора не требуется.
Я также удалил настройки имени таблицы и имени столбца, поскольку они настроены на то, что будет использоваться в любом случае, и удалил type:'text'
поскольку Hibernate знает тип поля, он может использовать его для типа столбца.
Также я добавил nullable: true
за targettypedescr
на основе SQL, который вы показали.
В целом, когда вы пытаетесь сопоставить устаревшие базы данных, используйте скрипт http://grails.org/doc/latest/ref/Command%20Line/schema-export.html чтобы посмотреть, как, по мнению Hibernate, должны выглядеть таблицы, Твик constraints
а также mapping
блоки, пока это не "достаточно близко".