昨天晚上碰到了一个问题,弄了老半天后来在别人的帮助下发现是mongodb存储HashMap类型字段时的问题,直接看代码吧:
//这是实体类中的那个HashMap类型的字段 private HashMap<String, String> properties; public HashMap<String, String> getProperties() { return properties; } public void setProperties(HashMap<String, String> properties) { this.properties = properties; }
这是monog保存实体时报的错误:
可以看出是数据库操作时出现的异常,再查看报错那地方的源码如下:
/** * If the given class format is not already present in the given map and * a format for this class name does not already exist, creates an * uninitialized format, adds it to the map, and also collects related * formats in the map. */ public Format createFormat(Class type, Map<String, Format> newFormats) { ...... /* * Although metadata is only needed for a complex type, call * getClassMetadata for all types to support checks for illegal * metadata on other types. */ //此处获取的metadata为NULL,基本上就可以得出应该是由于类型不匹配所导致的问题了 ClassMetadata metadata = model.getClassMetadata(className); /* Create format of the appropriate type. */ String proxyClassName = null; if (proxyClassMap != null) { proxyClassName = proxyClassMap.get(className); } if (proxyClassName != null) { format = new ProxiedFormat(this, type, proxyClassName); } else if (type.isArray()) { format = type.getComponentType().isPrimitive() ? (new PrimitiveArrayFormat(this, type)) : (new ObjectArrayFormat(this, type)); } else if (type.isEnum()) { format = new EnumFormat(this, type); } else if (type.getEnclosingClass() != null && type.getEnclosingClass().isEnum()) { /* * If the type is an anonymous class of an enum class, the format * which represents the enum class will be created. [#18357] */ format = new EnumFormat(this, type.getEnclosingClass()); } else if (type == Object.class || type.isInterface()) { format = new NonPersistentFormat(this, type); } else { if (metadata == null) { //此处为第799行报错的地方,所以应该是metadata的问题,再往上追踪metadata的出处 throw new IllegalArgumentException ("Class could not be loaded or is not persistent: " + className); } if (metadata.getCompositeKeyFields() != null && (metadata.getPrimaryKey() != null || metadata.getSecondaryKeys() != null)) { throw new IllegalArgumentException ("A composite key class may not have primary or" + " secondary key fields: " + type.getName()); } /* * Check for inner class before default constructor, to give a * specific error message for each. */ if (type.getEnclosingClass() != null && !Modifier.isStatic(type.getModifiers())) { throw new IllegalArgumentException ("Inner classes not allowed: " + type.getName()); } try { type.getDeclaredConstructor(); } catch (NoSuchMethodException e) { throw new IllegalArgumentException ("No default constructor: " + type.getName(), e); } if (metadata.getCompositeKeyFields() != null) { format = new CompositeKeyFormat (this, type, metadata, metadata.getCompositeKeyFields()); } else { EntityMetadata entityMetadata = model.getEntityMetadata(className); format = new ComplexFormat(this, type, metadata, entityMetadata); } } /* Collect new format along with any related new formats. */ newFormats.put(className, format); format.collectRelatedFormats(this, newFormats); return format; }
由于报错显示了BasicDbobject, 那我们再来看一下BasicDbobject的源码:
/* * Copyright (c) 2008-2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // BasicDBObject.java package com.mongodb; import com.mongodb.util.JSON; import org.bson.BasicBSONObject; import java.util.Map; /** * a basic implementation of bson object that is mongo specific. * A <code>DBObject</code> can be created as follows, using this class: * <blockquote><pre> * DBObject obj = new BasicDBObject(); * obj.put( "foo", "bar" ); * </pre></blockquote> */ public class BasicDBObject extends BasicBSONObject implements DBObject { private static final long serialVersionUID = -4415279469780082174L; /** * Creates an empty object. */ public BasicDBObject(){ } /** * creates an empty object * @param size an estimate of number of fields that will be inserted */ public BasicDBObject(int size){ super(size); } /** * creates an object with the given key/value * @param key key under which to store * @param value value to stor */ public BasicDBObject(String key, Object value){ super(key, value); } /** * Creates an object from a map. * @param m map to convert */ //由于实体中只有一个hashmap字段比较特殊,所以怀疑此处的Map可能有问题 public BasicDBObject(Map m) { super(m); } public boolean isPartialObject(){ return _isPartialObject; } public void markAsPartialObject(){ _isPartialObject = true; } /** * Returns a JSON serialization of this object * @return JSON serialization */ @Override public String toString(){ return JSON.serialize( this ); } @Override public BasicDBObject append( String key , Object val ){ put( key , val ); return this; } public Object copy() { // copy field values into new object BasicDBObject newobj = new BasicDBObject(this.toMap()); // need to clone the sub obj for (String field : keySet()) { Object val = get(field); if (val instanceof BasicDBObject) { newobj.put(field, ((BasicDBObject)val).copy()); } else if (val instanceof BasicDBList) { newobj.put(field, ((BasicDBList)val).copy()); } } return newobj; } private boolean _isPartialObject; }
//再打开BasicDBObject的父类,发现BasicBSONObject继承了java.util.LinkedHashMap //所以猜测可能是Bdb里面的vo不识别非JDK自身的HashMap实现 public class BasicBSONObject extends LinkedHashMap<String,Object> implements BSONObject { }
解决方案:
//修改set方法 public void setProperties(HashMap<String, String> properties) { HashMap<String, String> map = new HashMap<String, String>(); map.putAll(properties); this.properties = map; }
关于HashMap的更多信息请参考这位作者的文章:
http://itindex.net/detail/46645-hashmap-%E8%A7%A3%E6%9E%90
相关推荐
MongoDB存储结构设计是数据库架构中的一个重要议题,特别是在物联网(IoT)平台的背景下,它对于数据高效管理和处理至关重要。MongoDB是一种流行的NoSQL数据库,以其灵活性和高性能著称,但在设计存储结构时,需要考虑...
MongoDB 是一个流行的开源NoSQL数据库,而Java Driver for MongoDB是官方提供的用于Java应用程序与MongoDB之间通信的库。在本文档中,我们将探讨如何使用Java驱动程序进行基本的MongoDB操作,包括连接、添加、更新、...
MongoDB是一个流行的NoSQL数据库系统,由C++编写,设计为分布式文件存储,特别适合处理大规模Web应用程序的数据存储需求。它提供了高性能、可扩展性和丰富的数据模型,尤其是对于非结构化或半结构化的数据。MongoDB...
5. 并发问题:HashMap在并发环境下可能导致死循环,因为1.7版本使用尾插法。1.8版本虽然使用头插法,但在并发情况下仍然不安全。面试中,你可能会被问到如何在并发环境中安全地使用HashMap,这时可以提到`HashTable`...
如JNI)、堆(存储对象实例,线程共享)以及方法区(存储类的元数据,如类名、字段、方法信息,旧版JVM中称为永久代,现代JVM已改用元空间)。 JVM运行时内存主要关注新生代、老年代和持久代。新生代用于存放新创建...
- **Hash**:类似于HashMap,适合存储结构化的数据,如用户信息,允许对单个字段进行操作。例如,使用`HSET`、`HGETALL`、`HLEN`等命令进行操作,`HSET`可用于更新已存在的键值对。 Redis的其他数据类型还包括Set...
* GETSET db mongodb:设定key的值,并返回旧值,没有旧值,返回nil hash(哈希) Redis hash是一个键值(key=>value)对集合,特别适合用于存储对象。每个hash可以存储232-1键值对(约40亿)。 hash命令 * ...
- 如果需要存储多个用户的积分,可以使用数组或集合(如ArrayList、HashMap等)来维护。 2. **用户身份验证**: - 在获取或更新积分前,通常需要验证用户身份,这可能涉及用户ID、会话管理(session)或令牌...
6. **数据库集成**:更高级的实现可能会将数据存储在关系型数据库(如MySQL)或NoSQL数据库(如MongoDB)中,通过JDBC(Java Database Connectivity)接口与数据库进行交互,实现数据的CRUD(创建、读取、更新、删除...
开发者可能定义一些类来表示RFID标签及其属性,使用集合框架如ArrayList或HashMap来存储大量数据。例如,创建一个`RFIDTag`类,包含EPC、读取时间、位置等字段,以及相关的方法。 在数据存储方面,Java可以与各种...
这可能包括URL去重(使用HashSet或HashMap存储已访问的URL)和深度限制(限制爬虫访问的页面层级)。 数据存储方面,将抓取的信息保存到TXT文件是一个简单直接的方法。Java的FileWriter和BufferedWriter类可以用来...
3. **集合框架**:集合是存储和管理数据的关键,包括ArrayList、LinkedList、HashSet、HashMap等。面试中可能需要解释它们之间的区别,以及如何选择适当的集合类型。同时,了解并发容器如ConcurrentHashMap和...
这可以通过文件存储(如XML或JSON格式)、关系型数据库(如SQLite或MySQL)或者非关系型数据库(如MongoDB)来实现。如果选择文件存储,可以使用Java的序列化机制;如果是数据库,需要编写SQL语句或使用ORM框架(如...
2. **集合框架**:Java集合框架包括List(如ArrayList和LinkedList)、Set(如HashSet和TreeSet)和Map(如HashMap和TreeMap)。面试中会考察对它们的区别、性能特点以及如何选择合适的数据结构来解决问题。 3. **...
13. **数据库**:SQL基础,包括查询优化、事务处理、索引、存储过程,以及NoSQL数据库如MongoDB的基本操作。 14. **算法与数据结构**:虽然不是Java语言本身的一部分,但作为程序员,理解基本的排序算法(如快速...
2. 静态资源:对于较小且不常变动的数据集,开发者可能选择将省市列表存储在Java的静态字段中,或者在程序启动时加载到内存的HashMap等数据结构中。 3. JSON文件:另一种常见的方式是将数据存储在JSON文件中,例如...
1. **数据结构选择**:缓存通常使用哈希表(如HashMap)或者有序集合(如TreeMap)来存储数据,以实现快速查找。哈希表提供O(1)的查找效率,而有序集合则可以支持范围查询和按照某种排序规则访问。 2. **缓存策略**...
使用JAVA的数据结构如ArrayList或HashMap可以存储学生对象,同时数据库中的表结构应与之对应,确保数据的一致性。 2. 成绩管理:系统应能记录和查询学生的考试成绩,可能包括多门课程的成绩。可以设计一个成绩实体...
2. **集合框架**:Java集合框架是面试中经常讨论的话题,包括List(ArrayList、LinkedList)、Set(HashSet、TreeSet)和Map(HashMap、LinkedHashMap、TreeMap)接口及其实现类,以及泛型、迭代器、比较器等概念。...
深入理解MySQL,包括索引、事务、存储引擎等,并熟悉NoSQL数据库如MongoDB。 **十五、缓存** Redis的使用,如缓存策略、数据结构和操作命令。 **十六、JVM** 了解JVM内存模型,垃圾回收机制,性能调优等。 **...