java - Morphia-CodecConfigurationException : Can't find a codec for class - But class is registered

标签 java mongodb codec bson morphia

我遇到了一个尚未遇到的问题。 我想使用 Morphia 在 MongoDB 中存储带有嵌入对象的对象。

它似乎完全理解如何解/序列化顶级类,但不理解嵌入式类。这是两个类:

@Entity(value = "cb-homes", noClassnameStored = true)
@Getter
@Setter
@ToString
public class DatastoreHome extends DatastoreEntity {

    @Id
    private ObjectId id;
    @Indexed(options = @IndexOptions(unique = true, sparse = true, background = true))
    private UUID uniqueId;
    @Property("homes")
    @Embedded
    private Map<String, List<HomeLocation>> homeLocations;

    public List<String> getHomeNameList() {
        List<HomeLocation> locations = homeLocations.get(Bukkit.getServerName());
        if(locations == null) {
            locations = new ArrayList<>();
            homeLocations.put(Bukkit.getServerName(), locations);
        }
        return locations.stream().map(HomeLocation::getHomeName).collect(Collectors.toList());
    }

    public List<Location> getHomeLocationList() {
        List<HomeLocation> locations = homeLocations.get(Bukkit.getServerName());
        if(locations == null) {
            locations = new ArrayList<>();
            homeLocations.put(Bukkit.getServerName(), locations);
        }
        return locations.stream().map(HomeLocation::getLocation).collect(Collectors.toList());
    }

    public boolean hasSetBaseHome() {
        return getHomeLocation("home") != null;
    }

    public Location getBaseHomeLocation() {
        return getHomeLocation("home");
    }

    public Location getHomeLocation(String homeName) {
        List<HomeLocation> locations = homeLocations.get(Bukkit.getServerName());
        if(locations == null) {
            locations = new ArrayList<>();
            homeLocations.put(Bukkit.getServerName(), locations);
        }
        return locations.stream()
                .filter(location -> location.getHomeName().equals(homeName.toLowerCase()))
                .findAny()
                .map(HomeLocation::getLocation)
                .filter(location -> location.getWorld().getName() != "world")
                .orElse(null);
    }

    public boolean isHomeAlreadySet(String name) {
        return getHomeNameList().contains(name.toLowerCase());
    }

    public HomeLocation addHomeLocation(String homeName, Location location) {
        List<HomeLocation> locations = homeLocations.get(Bukkit.getServerName());
        if(locations == null) {
            locations = new ArrayList<>();
            homeLocations.put(Bukkit.getServerName(), locations);
        }
        if(isHomeAlreadySet(homeName)) {
            locations.remove(getHomeLocation(homeName));
        }
        HomeLocation homeLocation = new HomeLocation();
        homeLocation.setHomeName(homeName.toLowerCase());
        homeLocation.setLocation(location);
        homeLocations.get(Bukkit.getServerName()).add(homeLocation);
        return homeLocation;
    }

    public void removeBaseHomeLocation() {
        removeHomeLocation("home");
        addHomeLocation("home", new Location(Bukkit.getWorld("world"), 0, 0, 0, 0, 0));
    }

    public boolean removeHomeLocation(String homeName) {
        if(homeLocations.get(Bukkit.getServerName()) == null) {
            homeLocations.put(Bukkit.getServerName(), new ArrayList<>());
        }
        return homeLocations.get(Bukkit.getServerName()).removeIf(location -> location.getHomeName().equals(homeName));
    }

    static {
        datastore.ensureIndexes(DatastoreHome.class);
    }
}

@Embedded
@Getter
@Setter
@ToString
public class HomeLocation extends DatastoreEntity {

    @Id
    private ObjectId id;

    private String homeName;
    @Property("location")
    private Document document;

    public Location getLocation() {
        return deserialize(document);
    }

    public void setLocation(Location location) {
        document = serialize(location);
    }

    private Document serialize(Location location) {
        return new Document("world", location.getWorld())
                .append("x", location.getX())
                .append("y", location.getY())
                .append("z", location.getZ())
                .append("yaw", location.getYaw())
                .append("pitch", location.getPitch());
    }

    private Location deserialize(Document document) {
        return new Location(Bukkit.getWorld((String) get("world")), (double) get("x"), (double) get("y"), (double) get("z"), (float) get("yaw"), (float) get("pitch"));
    }

    private Object get(String key) {
        return document.get(key);
    }

    static {
        datastore.ensureIndexes(HomeLocation.class);
    }

}

正如您所看到的,这两个类都通过静态类初始化添加到 Morphia 索引中。这适用于所有其他类,但仅适用于 HomeLocation.class,它不起作用。

你们有什么想法可以解决这个问题吗? 我还尝试在初始化 Morphia 时手动将类添加到 Morphia 索引,但这也不起作用。

希望你能帮助我。

亲切的问候,

法比安·施密特

最佳答案

我知道这是一篇旧帖子,但分享我的解决方案希望对其他人有所帮助。

就您而言,您应该更改此设置:

@Property("homes")
@Embedded
private Map<String, List<HomeLocation>> homeLocations;

进入此:

@Embedded("homes")
private Map<String, List<HomeLocation>> homeLocations;

并且无需在 HomeLocation 类之上添加 @Embedded 注释。

关于java - Morphia-CodecConfigurationException : Can't find a codec for class - But class is registered,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47457777/

相关文章:

java - 如何在 Java 中使用 XPath 访问读取 XML 的值

ruby-on-rails - 如何修复 mongo 驱动程序 ruby​​ gem 中的 'Cannot start transaction # on session` 错误

mongodb - 将 2 个 mongoDB 集合中的数据合并到 1 个文档中

windows-xp - 无法播放 24 位音频

node.js - 在视频播放器中立即知道总视频时长 (ffmpeg/html)

webrtc - 如何获取我在 WebRTC 中使用的编解码器?

java - Android Fatal : Error java. 创建 Socket 时单击按钮时出现 lang.IllegalStateException

java - Tika in Action 书中的示例 Lucene StandardAnalyzer 不起作用

node.js - Mongodb updateone 与 $set 和 $currentDate 在第二次更新后抛出错误代码 40

java - Eclipse ADT - java 已启动但返回退出代码 = 13