首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

morphia Reference运用

2013-03-25 
morphia Reference使用bean idmongouri refmongo/property namedatabaseName valuecmac/

morphia Reference使用
<bean id="mongouri" ref="mongo"/> <property name="databaseName" value="cmac"/> <property name="user" value="${mongo.username}"/> <property name="password" value="${mongo.password}"/></bean><bean id="practisemorphia" ref="mongo"/> <property name="databaseName" value="practise"/> <property name="user" value="${mongo.username}"/> <property name="password" value="${mongo.password}"/></bean><bean id="datastore" factory-bean="morphia" factory-method="getDatastore"/><bean id="practiseds" factory-bean="practisemorphia" factory-method="getDatastore"/>

?

? ? ? ?我们为两个database分别写了两个BaseDao,让两个BaseDao分别持有不同的DatastoreImpl,没有问题,但是在使用Reference且lazy=true时,问题来了。如上的配置,spring初始化时先初始化datastore,再初始化practiseds,应用起来后,发现practiseds相关的@Reference(lazy=true)操作都正常,而datastore相关的@Reference(lazy=true)不正常,报的错误是MappingException。通过查看源码,发现getDatastore调用DatastoreHolder时是静态且单例的模式,因此当初始化practiseds时,就把之前的DatastoreHolder的静态变量覆盖了。Reference在lazy=true的情况下,会从DatastoreHolder里取当前的DatatoreImpl,而此时取到的都只是practiseds的DatatoreImpl,因此datastore相关的@Reference(lazy=true)通通抛出MappingException异常。

此问题的修复,只要在Dao对应方法里,加上以下代码:

DatastoreHolder.getInstance().set(super.getDs());

?//在BaseDao里定义DatastoreImpl成员变量并注入@Resource(name = "datastore")

?

public DatastoreImpl getDs() {return ds;}@Resource(name = "datastore")public void setDs(DatastoreImpl ds) {this.ds = (DatastoreImpl)ds;initType(((Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]));ensureIndexes();}

?

为了书写更加美观和便利,可以改造成AOP的方式

?

SupportReference.java

?

?

@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic @interface SupportReference {}

?

?

AbstractMorphiaReferenceAspect.aj

?

?

public abstract aspect AbstractMorphiaReferenceAspect {public AbstractMorphiaReferenceAspect() {}@SuppressAjWarnings("adviceDidNotMatch")Object around(Object model) : supportReferenceMethodExecution(model) {@SuppressWarnings("rawtypes")Class clazz = model.getClass().getSuperclass();try{@SuppressWarnings("unchecked")Method ds = clazz.getDeclaredMethod("getDs");DatastoreImpl datastoreimpl =(DatastoreImpl)ds.invoke(model);DatastoreHolder.getInstance().set(datastoreimpl);}catch(Exception ex){ex.printStackTrace();}Object result = proceed(model);return result;}protected abstract pointcut supportReferenceMethodExecution(Object model);}

?

?

MorphiaReferenceAspect.aj

?

?

public aspect MorphiaReferenceAspect extends AbstractMorphiaReferenceAspect {public MorphiaReferenceAspect() {super();}protected pointcut supportReferenceMethodExecution(Object model) : (execution(* com.hx.corebiz.*.dao.impl.*.*(..))) && @annotation(SupportReference) &&this(model);}

?

?

?aop.xml

?

<?xml version="1.0" encoding="UTF-8" ?><aspectj><aspects><aspect name="com.hx.corebase.aop.morphiareference.MorphiaReferenceAspect" /> </aspects><weaver options="-verbose"><include within="com.hx.corebiz.*.dao.impl.*" />        </weaver></aspectj>

?

在Dao类里,在需要使用@Reference(lazy=true)方法的加上Annotation?@SupportReference即可

?

?四、ignoreMisssing

ignoreMisssing会捕获Reference所有异常,如果不想看到一些烦人的异常,并让程序继续运行,ignoreMisssing=true是有必要的。比方说我们Reference到另一张表,某天另一张表的数据删除了,而开发人员也没有做关联数据的清理,此时如果ignoreMisssing=false(默认),就会抛出异常,这种情况下有必要指定ignoreMisssing=true。

热点排行