GWT + Hibernate many-to-one xml O/R Mapping: SerializationEx



我目前正在做一个GWT + Hibernate项目,该项目应该在一个已经定义和填充的数据库上一起工作。我收到一个

com.google.gwt.user.client.rpc.SerializationException

当我查询数据库时。

这是我的对象...

数据库:

-- Table: asset
CREATE TABLE IF NOT EXISTS asset
(
isin VARCHAR(12) NOT NULL,
mic_code VARCHAR(4) NOT NULL DEFAULT 'n.a.',
name VARCHAR(255) NOT NULL,
type_id VARCHAR(36) NOT NULL,
PRIMARY KEY (isin, mic_code),
INDEX(isin, mic_code),
FOREIGN KEY (type_id) REFERENCES asset_type(id)
)ENGINE=InnoDB;
-- Table: asset_type
CREATE TABLE IF NOT EXISTS asset_type
(
id VARCHAR(36) NOT NULL,
type VARCHAR(40) NOT NULL,
PRIMARY KEY (id)
)ENGINE=InnoDB;

资产.java:

public class Asset implements Serializable {
    private String isin;
    private String mic_code;
    private String name;
    private AssetType assetType;
    public Asset() {
        super();
    }
...

资产类型.java

public class AssetType implements Serializable {
    private String id;
    private String type;
    public AssetType() {
    }

最后是休眠 XML 文件:资产.hbm.xml

<hibernate-mapping>
    <class name="com.mygwtproject.shared.model.Asset" table="ASSET">
        <id name="isin" type="java.lang.String" access="field">
            <column name="ISIN" />
            <generator class="native" />
        </id>
        <property name="mic_code" type="java.lang.String" access="field">
            <column name="MIC_CODE" />
        </property>
        <property name="name" type="java.lang.String" access="field">
            <column name="NAME" />
        </property>
        <many-to-one name="assetType" class="com.mygwtproject.shared.model.types.AssetType" column="TYPE_ID" cascade="all" not-null="true"/>
    </class>
</hibernate-mapping>

资产类型.hbm.xml

<hibernate-mapping>
    <class name="com.mygwtproject.shared.model.types.AssetType" table="ASSET_TYPE">
        <id name="id" type="java.lang.String" column="ID"> 
            <generator class="native" />
        </id>
        <property name="type" type="java.lang.String" column ="TYPE" />
    </class>
</hibernate-mapping>

休眠.cfg.xml

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password">*****</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost/asset_db</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.current_session_context_class">thread</property>
        <property name="hibernate.query.factory_class">org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory</property>
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="use_sql_comments">true</property>
        <mapping resource="com/mygwtproject/shared/model/Asset.hbm.xml" />
        <mapping resource="com/mygwtproject/shared/model/types/AssetType.hbm.xml" />
    </session-factory>
</hibernate-configuration>

从日志:

Hibernate: 
    select
        assettype0_.ID as ID1_1_0_,
        assettype0_.TYPE as TYPE2_1_0_ 
    from
        ASSET_TYPE assettype0_ 
    where
        assettype0_.ID=?
09:43:09,139 TRACE BasicBinder:81 - binding parameter [1] as [VARCHAR] - [ee5bb49a-dc95-403a-9f77-864a9c342f25]
09:43:09,142 TRACE BasicExtractor:78 - extracted value ([TYPE2_1_0_] : [VARCHAR]) - [Stock]
Starting Jetty on port 8888
   [WARN] Exception while dispatching incoming RPC call
com.google.gwt.user.client.rpc.SerializationException: Type 'com.mygwtproject.shared.model.types.AssetType_$$_jvst77c_0' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = com.mygwtproject.shared.model.types.AssetType@7d617ac9

所以我的资产 -> 资产类型映射有问题,但我找不到它。任何帮助,不胜感激。谢谢

编辑:

mysql> select * from asset_type where id = 'ee5bb49a-dc95-403a-9f77-864a9c342f25';

返回

+--------------------------------------+-------+
| id                                   | type  |
+--------------------------------------+-------+
| ee5bb49a-dc95-403a-9f77-864a9c342f25 | Stock |
+--------------------------------------+-------+
1 row in set (0.00 sec)

从这里解决:

1. 创建对应的数据传输对象并替换休眠对象。

资产DTO.java

public class AssetDTO implements Serializable {
    private String isin;
    private String mic_code;
    private String name;
    private AssetTypeDTO assetType;
    public AssetDTO() {
        super();
    }
    public AssetDTO(String isin, String mic_code, String name,
            AssetTypeDTO assetType) {
        super();
        this.isin = isin;
        this.mic_code = mic_code;
        this.name = name;
        this.assetType = assetType;
    }
//incl. Getter + Setter
}

资产类型DTO.java

public class AssetTypeDTO implements Serializable {
    private String id;
    private String type;
    public AssetTypeDTO() {
        super();
    }
    public AssetTypeDTO(String id, String type) {
        super();
        this.id = id;
        this.type = type;
    }
   //incl. Getter + Setter
}

2. 向休眠对象添加新的构造函数。

资产.java

...
public Asset(AssetDTO dto) {
        this.isin = dto.getIsin();
        this.mic_code = dto.getMic_code();
        this.name = dto.getName();
        AssetTypeDTO assetTypeDTO = dto.getAssetType();
        if (assetTypeDTO != null) {
            this.assetType = new AssetType(assetTypeDTO.getId(),
                    assetTypeDTO.getType());
        }
 }
...

资产类型.java

public AssetType(AssetTypeDTO dto) {
        this.id = dto.getId();
        this.type = dto.getType();
    }

3. 修改 GWT RPC 组件。替换 Hibernate 对象

是服务.java

public List<Asset> getAssets();

与 DTO 一起。

public List<AssetDTO> getAssets();

IServiceAsync.java

public void getAssets(AsyncCallback<List<Asset>> callback);

public void getAssets(AsyncCallback<List<AssetDTO>> callback);

4. 修改服务实现。

ServiceImpl.java

...
@Override
public List<AssetDTO> getAssets() {
    ...
    Query q = session.createQuery("from Asset");
    List<Asset> assets = new ArrayList<Asset>(q.list());
    List<AssetDTO> assetsDto = new ArrayList<AssetDTO>();
    if (assets != null) {
        for (Asset asset : assets) {
            assetsDto.add(createAssetDTO(asset));
        }
    }
    session.getTransaction().commit();
    return assetsDto;
}
public AssetDTO createAssetDTO(Asset asset) {
    AssetTypeDTO assetTypeDto = new AssetTypeDTO(asset.getAssetType()
                .getId(), asset.getAssetType().getType());
    AssetDTO result = new AssetDTO(asset.getIsin(), asset.getMicCode(),
                asset.getName(), assetTypeDto);
    return result;
}
...
5. 将 Hibernate

对象(Asset、AssetType)移动到 server 包,将 DTO(AssetDTO、AssetTypeDTO)移动到shared包中,并更新 Hibernate xml 文件中的路径。

最新更新