`
leonzhx
  • 浏览: 791711 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Morphia always stores classname for embedded collection

阅读更多

Today, I found a problem that Morphia alwasy stores classname for embedded collection when updating it.  Here is my POJO example :

 

@Entity(noClassnameStored = true)
@Indexes({@Index(name="idx_meta" , value="meta.n, meta.v"), @Index(name="idx_meta_creator", value="meta.c")})

public class ResourceDO  {

	@Id
	private String systemId;
        ...
        
        @Embedded
	private Set<ResourceMetaDO> meta;

       ...

       public Set<ResourceMetaDO> getMetaEntries(){
		return meta;
	}
 }

@Embedded(concreteClass=ResourceMetaDO.class)
public class ResourceMetaDO {

	//name
	private String n;
	
	//value
	private String v;
	
	//creator
	private String c;

        ...
 }


	

 I mapped both ResourceDO.class and ResourceMetaDO.class at the startup of my application using Morphia.map(). 

 

 When I used AdvancedDatastore.save() or AdvancedDatastore.insert() to save or update resource, all went well.

 

 However when I tried to use the following codes to update the meta :

updateMeta( ResourceDO r )
{
    Query<ResourceDO> query = ds.createQuery(ResourceDO.class).filter("_id", r.getSystemId() );
    UpdateOperations<ResourceDO> update =ds.createUpdateOperations(ResourceDO.class).set("meta", r.getMetaEntries());
    dao.getDatastore().update(query, update);
}
    

 The meta was stored with classname. When I looked into UpdateOpsImpl.java :

 

protected void add(UpdateOperator op, String f, Object value, boolean convert) {
		if (value == null)
			throw new QueryException("Val cannot be null");

		Object val = null;
		MappedField mf = null;
		if (validateNames || validateTypes) {
			StringBuffer sb = new StringBuffer(f);
			mf = Mapper.validate(clazz, mapr, sb, FilterOperator.EQUAL, val, validateNames, validateTypes);
			f = sb.toString();
		}

		if (convert)
			if (UpdateOperator.PULL_ALL.equals(op) && value instanceof List)
				val = toDBObjList(mf, (List<?>) value);
			else
				val = mapr.toMongoObject(mf, null, value);

		
		...
	}

 

and Mapper.java

public Object toMongoObject(MappedField mf, MappedClass mc, Object value) {
		Object mappedValue = value;
		
		//convert the value to Key (DBRef) if the field is @Reference or type is Key/DBRef, or if the destination class is an @Entity
		if ((mf!=null && (	mf.hasAnnotation(Reference.class) || 
							mf.getType().isAssignableFrom(Key.class) || 
							mf.getType().isAssignableFrom(DBRef.class))
						 ) || (mc != null && mc.getEntityAnnotation() != null)) {
			try {
				Key<?> k = (value instanceof Key) ? (Key<?>)value : getKey(value);
				mappedValue = keyToRef(k);
			} catch (Exception e) {
				log.debug("Error converting value(" + value + ") to reference.", e);
				mappedValue = toMongoObject(value, false);
			}
		}//serialized
		else if (mf!=null && mf.hasAnnotation(Serialized.class))
			try {
				mappedValue = Serializer.serialize(value, !mf.getAnnotation(Serialized.class).disableCompression());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		//pass-through
		else if (value instanceof DBObject)
			mappedValue = value;
		else {
			mappedValue = toMongoObject(value, EmbeddedMapper.shouldSaveClassName(value, mappedValue, mf));
			if (mappedValue instanceof DBObject && !EmbeddedMapper.shouldSaveClassName(value, mappedValue, mf))
				((DBObject) mappedValue).removeField(CLASS_NAME_FIELDNAME);
		}
		
		return mappedValue;
	}

 and EmbeddedMapper.java

 

 

public static boolean shouldSaveClassName(Object rawVal, Object convertedVal, MappedField mf) {
		if (rawVal == null || mf == null)
			return true;
		if (mf.isSingleValue())
			return !(mf.getType().equals(rawVal.getClass()) && !(convertedVal instanceof BasicDBList));
		else
			if ( convertedVal != null && 
				 convertedVal instanceof DBObject && 
				 !mf.getSubClass().isInterface() && 
				 !Modifier.isAbstract(mf.getSubClass().getModifiers()) && 
				 mf.getSubClass().equals(rawVal.getClass()))
				return false;
			else 
				return true;
	}

 

It will always store classname for embedded collection even you have definite concreteClass for the embedded field.

 

 So , I swtiched to the following tagging :

 

@Entity(noClassnameStored = true)
public class ResourceMetaDO implements IMetaEntry {
        @Id
	private ObjectId id;
	
	//name
	private String n;
	
	//value
	private String v;
	
	//creator
	private String c;
	
        ...
}

 

It works now. And note the id filed will not be set automatically by morphia if you only use the ResourceMetaDO class as the embedded field of ResourceDO

3
3
分享到:
评论

相关推荐

    使用Morphia框架操作mongodb

    在Java开发中,Morphia是一个优秀的对象数据映射(ODM)框架,它简化了与MongoDB之间的交互,使得开发者可以像操作传统关系型数据库那样操作文档数据库。本文将深入探讨如何使用Morphia框架来操作MongoDB。 首先,...

    morphia-0.99.jar

    morphia-0.99.jar 最新版本。

    morphia所用到的jar包

    MongoDB是一个流行的开源、分布式文档数据库,而Morphia是一个Java对象数据映射(Object-Document Mapping, ODM)框架,用于简化与MongoDB的交互。在这个压缩文件中,我们有两个重要的jar包:mongo-2.7.3.jar和...

    morphia.jar和mongo.jar

    标题中的“morphia.jar”和“mongo.jar”指的是两个与MongoDB数据库操作相关的Java库文件。MongoDB是一个流行的开源、分布式文档型数据库,而Morphia则是Java开发人员用来操作MongoDB的一个对象数据映射(ODM)框架...

    morphia基于mongodb的基本开发

    morphia基于mongodb的基本开发

    morphia-1.3.2.jar

    morphia-1.3.2.jar

    Morphia和MongoDB学习总结<三>

    **标题:“Morphia和MongoDB学习总结&lt;三&gt;”** 在本文中,我们将深入探讨Morphia,一个用于Java的MongoDB对象数据映射(ODM)库,以及它如何与MongoDB数据库进行交互。Morphia简化了在MongoDB中存储和检索Java对象的...

    spring MVC morphia mongo 整合的例子

    Spring MVC、Morphia 和 MongoDB 是三个在Java开发中常用于构建Web应用程序的关键技术。Spring MVC 是Spring框架的一部分,提供了一种模型-视图-控制器(MVC)架构模式,帮助开发者组织和处理Web应用的业务逻辑。...

    Mongo的ORM框架的学习Morphia

    在本文中,我们将探讨MongoDB的ORM框架Morphia,并结合Spring Data MongoDB的使用来创建一个集成应用。ORM(对象关系映射)框架是将数据库操作转化为对象模型的方法,简化了开发过程,使得开发者可以专注于业务逻辑...

    使用 Morphia 和 MongoDB 实现域模型持久性(ZZ)

    Morphia 是一个 Java 框架,它为 MongoDB 提供了对象数据映射(Object Data Mapping,简称 ODM)功能,使得开发者可以更方便地在 Java 对象与 MongoDB 文档之间进行转换。本篇文章将详细介绍如何使用 Morphia 和 ...

    Morphia开发简介.pdf

    【Morphia开发简介】 Morphia是一款针对MongoDB数据库的Java对象关系映射(ORM)框架,它的主要目标是让Java开发者能够以面向对象的方式处理数据库操作,从而减轻数据库设计的复杂性,使开发者能更专注于业务逻辑。...

    Morphia 操作 MongoDB.docx

    【MongoDB与Morphia简介】 MongoDB是一款流行的NoSQL数据库系统,以其灵活的数据模型、高可用性和可扩展性而受到广泛欢迎。Morphia是针对MongoDB的一个Java持久层框架,它提供了简单易用的API,使得开发者能够方便地...

    morphia-1.00-SNAPSHOT.jar

    morphia mongo db OR-mapping mongo db再带的CRUD 太麻烦了, 一个不错的框架 类似 Hibernate

    Morphia 操作 MongoDB.pdf

    Morphia 是一个 Java ORM(对象关系映射)库,用于简化 MongoDB 的数据操作,将数据模型与数据库文档之间的转换自动化。在本文中,我们将深入探讨如何使用 Morphia 进行 MongoDB 的操作。 首先,为了在 Java 项目中...

    Morphia使用问题及解决方案集锦

    ### Morphia使用问题及解决方案集锦 #### 一、使用update方法更新带有@Reference注解的集合字段 在使用Morphia框架时,经常会遇到需要更新具有`@Reference`注解的集合字段的情况。例如,在更新`UserGroup`中的成员...

    Morphia一个nosql的ORM框架

    **Morphia:一个NoSQL的ORM框架** Morphia是一个强大的Java ORM(对象关系映射)框架,专为MongoDB数据库设计。它允许开发者使用Java对象来操作数据库,消除了与传统SQL数据库交互时所需的SQL语法,使开发更加便捷...

    mongodb+springmvc+morphia

    后续提交放在https://github.com/zdsiyan/watermelon 上, 用eclipse导入该工程需安装m2eclipse,jetty等查件. 另外.settings下的org.eclipse.wst.common.component文件如下: ...&lt;/project-modules&gt;

    快速入门:2分钟介绍关于Morphia

    **Morphia 概述** Morphia 是一个基于 Java 的开源对象数据映射(Object Document Mapping,简称 ODM)框架,它为 MongoDB 提供了简单易用的接口。MongoDB 是一个流行的分布式文档数据库系统,它以 JSON 格式存储...

Global site tag (gtag.js) - Google Analytics