@Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        name = ExternalizableUtil.getInstance().readSafeUTF(in);
        ExternalizableUtil.getInstance().readExternalizableCollection(in, occupants, getClass().getClassLoader());
        startTime = ExternalizableUtil.getInstance().readLong(in);
        endTime = ExternalizableUtil.getInstance().readLong(in);
        lockedTime = ExternalizableUtil.getInstance().readLong(in);
        ExternalizableUtil.getInstance().readSerializableCollection(in, owners, getClass().getClassLoader());
        ExternalizableUtil.getInstance().readSerializableCollection(in, admins, getClass().getClassLoader());
        ExternalizableUtil.getInstance().readSerializableMap(in, members, getClass().getClassLoader());
        ExternalizableUtil.getInstance().readSerializableCollection(in, outcasts, getClass().getClassLoader());
        naturalLanguageName = ExternalizableUtil.getInstance().readSafeUTF(in);
        description = ExternalizableUtil.getInstance().readSafeUTF(in);
        canOccupantsChangeSubject = ExternalizableUtil.getInstance().readBoolean(in);
        maxUsers = ExternalizableUtil.getInstance().readInt(in);
        rolesToBroadcastPresence.addAll(ExternalizableUtil.getInstance().readStringList(in).stream().map(Role::valueOf).collect(Collectors.toSet())); // This uses stringlist for compatibility with Openfire 4.6.0. Can be replaced the next major release.
        publicRoom = ExternalizableUtil.getInstance().readBoolean(in);
        persistent = ExternalizableUtil.getInstance().readBoolean(in);
        retireOnDeletion = ExternalizableUtil.getInstance().readBoolean(in);
        moderated = ExternalizableUtil.getInstance().readBoolean(in);
        membersOnly = ExternalizableUtil.getInstance().readBoolean(in);
        canOccupantsInvite = ExternalizableUtil.getInstance().readBoolean(in);
        password = ExternalizableUtil.getInstance().readSafeUTF(in);
        canAnyoneDiscoverJID = ExternalizableUtil.getInstance().readBoolean(in);
        canSendPrivateMessage = ExternalizableUtil.getInstance().readSafeUTF(in);
        logEnabled = ExternalizableUtil.getInstance().readBoolean(in);
        preserveHistOnRoomDeletion = ExternalizableUtil.getInstance().readBoolean(in);
        loginRestrictedToNickname = ExternalizableUtil.getInstance().readBoolean(in);
        canChangeNickname = ExternalizableUtil.getInstance().readBoolean(in);
        registrationEnabled = ExternalizableUtil.getInstance().readBoolean(in);
        fmucEnabled = ExternalizableUtil.getInstance().readBoolean(in);
        if (ExternalizableUtil.getInstance().readBoolean(in)) {
            fmucOutboundNode = (JID) ExternalizableUtil.getInstance().readSerializable(in);
        } else {
            fmucOutboundNode = null;
        }
        if (ExternalizableUtil.getInstance().readBoolean(in)) {
            final int i = ExternalizableUtil.getInstance().readInt(in);
            fmucOutboundMode = FMUCMode.values()[i];
        } else {
            fmucOutboundMode = null;
        }
        if (ExternalizableUtil.getInstance().readBoolean(in)) {
            fmucInboundNodes = new HashSet<>();
            ExternalizableUtil.getInstance().readSerializableCollection(in, fmucInboundNodes, getClass().getClassLoader());
        } else {
            fmucInboundNodes = null;
        }
        subject = ExternalizableUtil.getInstance().readSafeUTF(in);
        roomID = ExternalizableUtil.getInstance().readLong(in);
        creationDate = new Date(ExternalizableUtil.getInstance().readLong(in));
        if (ExternalizableUtil.getInstance().readBoolean(in)) {
            modificationDate = new Date(ExternalizableUtil.getInstance().readLong(in));
        }
        if (ExternalizableUtil.getInstance().readBoolean(in)) {
            emptyDate = new Date(ExternalizableUtil.getInstance().readLong(in));
        }
        savedToDB = ExternalizableUtil.getInstance().readBoolean(in);
        String subdomain = ExternalizableUtil.getInstance().readSafeUTF(in);
        mucService = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(subdomain);
        if (mucService == null) throw new IllegalArgumentException("MUC service not found for subdomain: " + subdomain);
        roomHistory = new MUCRoomHistory(this, new HistoryStrategy(getJID(), mucService.getHistoryStrategy()));

        this.iqOwnerHandler = new IQOwnerHandler(this);
        this.iqAdminHandler = new IQAdminHandler(this);
        this.fmucHandler = new FMUCHandler(this);

        roomHistory = (MUCRoomHistory) ExternalizableUtil.getInstance().readSerializable(in);
        selfOccupantData = (MUCOccupant) ExternalizableUtil.getInstance().readSerializable(in);
    }
Saves the room configuration to the DB. After the room has been saved to the DB it will
become persistent.
xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCRoom.java