【问题标题】:Hibernate generates new Id instead of getting Id from database?Hibernate 生成新的 Id 而不是从数据库中获取 Id?
【发布时间】:2016-07-06 16:04:34
【问题描述】:

这里是 Hibernate 的新手,所以我可能只是在某个地方误解和/或犯了错误。

最近我在我的独立 Java 应用程序中实现了 Hibernate。我有一个复杂的数据库结构,有很多关联,还有一个超子类结构,每个都有自己的表。问题如下:

当我要求 Hibernate 从其中一个子类表中选择几行时,我每行得到一个与数据库中不同的 Id。当我想在其他地方使用这个 Id (获取外键违规)时,这会导致很多问题。该特定行的 Id 始终相同,但我无法在数据库中的任何位置找到 Id,不在同一个表或其他表中。

我的超类/子类的 Hibernate 映射如下:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="bliksem_prototype.model.Endpoint" table="Bliksem_Endpoint" schema="dbo" catalog="WMB_Application_Operations_ONTW" optimistic-lock="version">
    <id name="endpointId">
        <column name="EndpointId" length="36" />
        <generator class="uuid2" />
    </id>
    <property name="endpointType" type="string">
        <column name="EndpointType" length="30" not-null="true" />
    </property>
    <set name="endpointFlows" table="Bliksem_Link_Endpoint_Flow" inverse="true" lazy="true" fetch="select">
        <key>
            <column name="EndpointId" length="36" not-null="true" />
        </key>
        <one-to-many class="bliksem_prototype.model.EndpointFlow" />
    </set>
    <joined-subclass name="bliksem_prototype.model.Queue" table="Bliksem_Queue" schema="dbo" catalog="WMB_Application_Operations_ONTW" extends="bliksem_prototype.model.Endpoint">
        <key column="QueueId"/>
        <many-to-one name="cluster" class="bliksem_prototype.model.Cluster" fetch="select">
            <column name="ClusterName" length="30" />
        </many-to-one>
        <many-to-one name="queueManager" class="bliksem_prototype.model.QueueManager" fetch="select">
            <column name="QueueManagerName" length="30" not-null="true" />
        </many-to-one>
        <property name="queueName" type="string">
            <column name="QueueName" length="70" not-null="true" />
        </property>
        <property name="queueType" type="string">
            <column name="QueueType" length="30" not-null="true" />
        </property>
        <property name="maxDepth" type="java.lang.Long">
            <column name="MaxDepth" precision="10" scale="0" />
        </property>
        <property name="maxMessageLength" type="java.lang.Long">
            <column name="MaxMessageLength" precision="15" scale="0" />
        </property>
        <set name="queueDestinationRouters" table="Bliksem_Link_Queue_DestinationRouter" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="QueueId" length="36" not-null="true" />
            </key>
            <one-to-many class="bliksem_prototype.model.QueueDestinationRouter" />
        </set>
    </joined-subclass>
    <joined-subclass name="bliksem_prototype.model.FileNode" table="Bliksem_FileNode" schema="dbo" catalog="WMB_Application_Operations_ONTW" extends="bliksem_prototype.model.Endpoint">
        <key column="FileNodeId"/>
        <property name="fileNodeName" type="string">
            <column name="FileNodeName" length="70" not-null="true" />
        </property>
        <property name="mapName" type="string">
            <column name="MapName" length="70" />
        </property>          
    </joined-subclass> 
    <joined-subclass name="bliksem_prototype.model.Webservice" table="Bliksem_Webservice" schema="dbo" catalog="WMB_Application_Operations_ONTW" extends="bliksem_prototype.model.Endpoint">
        <key column="WebserviceId"/>
        <property name="webserviceName" type="string">
            <column name="WebserviceName" length="70" not-null="true" />
        </property>
    </joined-subclass>
</class>
</hibernate-mapping>

如果我将 generator class 更改为 assigned 并自己分配 UUID,我仍然会遇到同样的问题。

其中一个子类的示例:

public class FileNode extends Endpoint implements java.io.Serializable,      Comparable<FileNode> {


 private String fileNodeName;
 private String mapName;

public FileNode() {
}

public FileNode(UUID fileNodeId, String fileNodeName, String mapName) {
    super(fileNodeId, "FileNode");
    this.fileNodeName = fileNodeName;
    this.mapName = mapName;
}

public FileNode(UUID fileNodeId, String fileNodeName) {
    super(fileNodeId, "FileNode");
    this.fileNodeName = fileNodeName;
}

public String getFileNodeName() {
    return this.fileNodeName;
}

public void setFileNodeName(String fileNodeName) {
    this.fileNodeName = fileNodeName;
}
public String getMapName() {
    return this.mapName;
}

public void setMapName(String mapName) {
    this.mapName = mapName;
}

@Override
public int compareTo(FileNode o) {
    return this.getFileNodeName().compareTo(o.getFileNodeName());
}
}

超类:

public class Endpoint implements java.io.Serializable {


 private UUID endpointId;
 private String endpointType;
 private Set endpointFlows = new HashSet(0);
 @Transient
 private String environmentName;

public Endpoint() {
}

public Endpoint(UUID endpointId, String endpointType, Set endpointFlows) {
    this.endpointId = endpointId;
    this.endpointType = endpointType;
    this.endpointFlows = endpointFlows;
}

public Endpoint(UUID endpointId, String endpointType) {
    this.endpointId = endpointId;
    this.endpointType = endpointType;
}

public Endpoint(UUID endpointId, String endpointType, String environmentName) {
    this.endpointId = endpointId;
    this.endpointType = endpointType;
    this.environmentName = environmentName;
}

public UUID getEndpointId() {
    return endpointId;
}

public void setEndpointId(UUID endpointId) {
    this.endpointId = endpointId;
}

public String getEndpointType() {
    return this.endpointType;
}

public void setEndpointType(String endpointType) {
    this.endpointType = endpointType;
}

public String getEnvironmentName() {
    return environmentName;
}

public void setEnvironmentName(String environmentName) {
    this.environmentName = environmentName;
}

public Set getEndpointFlows() {
    return endpointFlows;
}

public void setEndpointFlows(Set endpointFlows) {
    this.endpointFlows = endpointFlows;
}
}

插入其中一个子类效果很好,我不必插入自动运行的超类。 注意:我不完全确定我的问题是否只是因为超类/子类构造,但这是我第一次遇到它的一些问题。

我对 Hibernate 有什么遗漏或理解不正确?

【问题讨论】:

  • 更正:我对随机不同的表有同样的问题,它没有超/子类结构。

标签: java hibernate


【解决方案1】:

经过一番测试,我突然意识到 Hibernate 给出的键和数据库中的键包含相同的字符,只是顺序不同。又在谷歌上搜索了一下,找到了这个话题:

Problem obtaining entities with uniqueidentifier primary key

似乎是这样:Java UUID (java.util.UUID) 和 SQL Server 唯一标识符是两个不同的东西。不知何故,Hibernate 设法映射字符,但不是顺序(尽管两个键的最后部分是相同的)。我通过不被接受为答案的答案解决了我的问题,并添加了type="uuid-char",它可以工作。我还可以让 Hibernate 使用&lt;generator class="uuid2" /&gt; 生成 UUID。

我确实想指出 type="uuid-char" 甚至可能不是必需的,因为 Hibernate 似乎确实在没有它的情况下进行映射(尽管它可能会令人困惑)。如果使用 uuid-char,则在使用 Hibernate 使用 hql/query 调用数据库并通过 UUID 请求行时,还需要将参数转换为 String。如果将 UUID 作为参数填写,可能无法得到结果。

【讨论】:

    猜你喜欢
    • 2020-11-23
    • 2012-11-13
    • 2013-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多