我正在使用GORM提供的模式模式将现有的Grails 3项目调整为多租户结构,而且当我指定租户时,我无法让GORM监听器工作。
我的听众看起来像这样:
@CompileStatic
class VehicleListenerService {
@Listener(Vehicle)
void onPreInsertEvent(PreInsertEvent event) {
println "*** Vehicle preInsert"
event.entityAccess.setProperty('model', 'preInsert')
}
@Listener(Vehicle)
void onPreUpdateEvent(PreUpdateEvent event) {
println "*** Vehicle preUpdate"
event.entityAccess.setProperty('model', 'preUpdate')
}
}
因此,每次创建或更新车辆时,都应将其模型更改为preInsert或preUpdate。
当前租户由URL中指定的子域确定。如果我访问没有子域的应用程序(通过qazxswpoi),则监听器按预期工作,但如果我提供子域(http://localhost:8080),则监听器不会执行任何操作,并且车辆模型不会更改。
我需要做些什么才能让GORM监听器与任何租户一起工作?
我创建了一个重现错误的示例项目(http://test.localhost:8080)。
在Grails Slack频道和更多研究的帮助下,我想出了一个解决方案。
首先,侦听器服务必须扩展AbstractPersistenceEventListener:
https://github.com/sneira/mtschema
现在我们可以在Bootstrap.groovy中为每个模式创建一个服务实例(默认值除外),并将其添加到我们的应用程序中:
@CompileStatic
class VehicleListenerService extends AbstractPersistenceEventListener {
protected VehicleListenerService(Datastore datastore) {
super(datastore)
}
@Override
protected void onPersistenceEvent(AbstractPersistenceEvent event) {
String newModel =
event.eventType == EventType.PreInsert ? 'preInsert' : 'preUpdate'
event.entityAccess.setProperty('model', newModel)
}
@Override
boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
boolean supportsEvent = eventType.isAssignableFrom(PreInsertEvent) ||
eventType.isAssignableFrom(PreUpdateEvent)
return supportsEvent
}
}
我已将完整的代码上传到def init = { servletContext ->
def ctx = grailsApplication.mainContext
['TEST', 'TEST2'].each { String name ->
HibernateDatastore ds = hibernateDatastore.getDatastoreForConnection(name)
VehicleListenerService listener = new VehicleListenerService(ds)
ctx.addApplicationListener(listener)
}
}
。