无法使用 Morphia 从 Mongo db 中提取 - 没有可用的构造函数

Posted

技术标签:

【中文标题】无法使用 Morphia 从 Mongo db 中提取 - 没有可用的构造函数【英文标题】:Not able to pull from Mongo db using Morphia - No usable constructor 【发布时间】:2015-12-24 08:33:24 【问题描述】:

所以我试图将 sha265 中的密码保存到 mongo db 中并使用Apache Shiro 框架来授权用户登录,同时尝试从数据库中提取我得到 morphia 运行时异常,这里是代码:

用户类别:

public class User implements Serializable

        @Id 
        private ObjectId id; 
        private String name; 
        private String password;
        private SimpleByteSource passwordSalt;

        @Embedded 
        private TenantId tenantId; 
        private Set<String> roles = new HashSet<>();



        @Override
        public String toString() 
            return "User [id=" + id + ", name=" + name + ", password="
                    + password + ", passwordS, tenantId=" + tenantId + ", roles=" + roles + "]";
        
        public SimpleByteSource getPasswordSalt() 
            return passwordSalt;
        
        public void setPasswordSalt(SimpleByteSource passwordSalt) 
            this.passwordSalt = passwordSalt;
        
        public ObjectId getId() 
            return id;
        
        public void setId(ObjectId id) 
            this.id = id;
        
        public String getName() 
            return name;
        
        public void setName(String name) 
            this.name = name;
        
        public String getPassword() 
            return password;
        
        public void setPassword(String password) 
            this.password = password;
        
        public TenantId getTenantId() 
            return tenantId;
        
        public void setTenantId(TenantId tenantId) 
            this.tenantId = tenantId;
        
        public Set<String> getRoles() 
            return roles;
        
        public void setRoles(Set<String> roles) 
            this.roles = roles;
         


测试类:

public static void main(String[] args) 
        MongoClient m_mongoClient = new MongoClient("127.0.0.1",27017);
        Morphia  m_morphiaMongoDB = new Morphia();
        Datastore ds = m_morphiaMongoDB.createDatastore(m_mongoClient, "test");

        RandomNumberGenerator rng = new SecureRandomNumberGenerator();
        SimpleByteSource salt = (SimpleByteSource) rng.nextBytes();
        String hashedPasswordBase64 = new Sha256Hash("1234", salt, 1024).toBase64();
        User temp = new User();

        temp.setName("Myname");
        //temp.setPassword("1234");
        temp.setPassword(hashedPasswordBase64);
        temp.setPasswordSalt(salt);

        ds.save(temp);

        User user = ds.find(User.class).field("name").equal("Myname").get();
        System.out.println(user);

    

我正在使用 Shiro 和 Morphia,这就是我得到的:

Exception in thread "main" java.lang.RuntimeException: org.mongodb.morphia.mapping.MappingException: No usable constructor for org.apache.shiro.util.SimpleByteSource
    at org.mongodb.morphia.mapping.EmbeddedMapper.fromDBObject(EmbeddedMapper.java:171)
    at org.mongodb.morphia.mapping.Mapper.readMappedField(Mapper.java:617)
    at org.mongodb.morphia.mapping.Mapper.fromDb(Mapper.java:592)
    at org.mongodb.morphia.mapping.Mapper.fromDBObject(Mapper.java:306)
    at org.mongodb.morphia.query.MorphiaIterator.convertItem(MorphiaIterator.java:79)
    at org.mongodb.morphia.query.MorphiaIterator.processItem(MorphiaIterator.java:65)
    at org.mongodb.morphia.query.MorphiaIterator.next(MorphiaIterator.java:60)
    at org.mongodb.morphia.query.QueryImpl.get(QueryImpl.java:421)
    at com.roi.shiro.realm.temp.main(temp.java:31)
Caused by: org.mongodb.morphia.mapping.MappingException: No usable constructor for org.apache.shiro.util.SimpleByteSource
    at org.mongodb.morphia.mapping.DefaultCreator.getNoArgsConstructor(DefaultCreator.java:140)
    at org.mongodb.morphia.mapping.DefaultCreator.createInst(DefaultCreator.java:109)
    at org.mongodb.morphia.mapping.DefaultCreator.createInstance(DefaultCreator.java:27)
    at org.mongodb.morphia.mapping.DefaultCreator.createInstance(DefaultCreator.java:35)
    at org.mongodb.morphia.mapping.DefaultCreator.createInstance(DefaultCreator.java:45)
    at org.mongodb.morphia.mapping.EmbeddedMapper.fromDBObject(EmbeddedMapper.java:161)
    ... 8 more
Caused by: java.lang.NoSuchMethodException: org.apache.shiro.util.SimpleByteSource.<init>()
    at java.lang.Class.getConstructor0(Class.java:3074)
    at java.lang.Class.getDeclaredConstructor(Class.java:2170)
    at org.mongodb.morphia.mapping.DefaultCreator.getNoArgsConstructor(DefaultCreator.java:136)
    ... 13 more

SimpleByteSource 有以下构造函数:

 public SimpleByteSource(byte[] bytes) 
        this.bytes = bytes;
     

有什么想法吗?

【问题讨论】:

【参考方案1】:

您无法使用 Morphia 保存该对象。 Morphia 在填充其字段之前需要一个零参数构造函数来创建类。您需要将该 byte[] 保存在 User 类的字段中。

【讨论】:

我刚刚有了另一个想法。您可能可以为该字段编写一个转换器,该转换器将采用byte[],创建SimpleByteSource,然后返回它。这也可以工作并保留您的对象模型。 fwiw,只要每个字段都存在于构造函数中,Morphia 2.2 就支持使用构造函数。

以上是关于无法使用 Morphia 从 Mongo db 中提取 - 没有可用的构造函数的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 的 Morphia、Mongo4j 和 Spring 数据如何比较? [关闭]

将本地 mongo db 迁移到 atlas 后无法从 atlas 获取记录

无法通过 Spark 连接到 Mongo DB

通过 R 连接时无法在 mongo DB 中查看集合

播放 Morphia,无法获取(通用)嵌入对象的列表内容

在 K3s 中使用 Kubernetes 服务端点的本地 Mongo DB 容器访问不起作用