GWT + Hibernate多对一xml O / R映射:SerializationException

时间:2015-01-23 09:10:08

标签: java xml hibernate gwt hibernate-mapping

我目前正在开发一个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;

Asset.java:

public class Asset implements Serializable {

    private String isin;
    private String mic_code;
    private String name;
    private AssetType assetType;

    public Asset() {
        super();
    }
...

AssetType.java

public class AssetType implements Serializable {

    private String id;
    private String type;

    public AssetType() {
    }

最后是hibernate xml文件: Asset.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>

AssetType.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>

的hibernate.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

所以我的资产出现了问题 - &gt; AssetType映射,但我找不到它。任何帮助表示赞赏。感谢

修改

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 个答案:

答案 0 :(得分:1)

来自here的解决方案:

<强> 1。创建对应的数据传输对象并替换hibernate对象。

AssetDTO.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
}

AssetTypeDTO.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。在hibernate对象中添加一个新的构造函数。

Asset.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());
        }
 }
...

AssetType.java

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

第3。修改GWT RPC组件。 替换

中的Hibernate对象

IService.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文件中的路径。