【问题标题】:override identitycolumn hibernate mssql覆盖标识列休眠 mssql
【发布时间】:2016-05-03 07:42:36
【问题描述】:

我必须使用休眠管理 2 个 DB (mssql) 之间的数据传输。 当我使用session.get() 从一个数据库加载一个对象时,它已经有一个私钥。然后我需要用anotherSession.replicate(Object o) 将它持久化到另一个数据库。 我的问题是,给定的 PK 没有保留,而是被另一个替换。

PS:srcTable 和 destTable 都有 PK 生成标识,需要保持这种状态。

【问题讨论】:

  • 寻找SET IDENTITY_INSERT TableName ON/OFF...

标签: java sql-server hibernate


【解决方案1】:

如果您使用生成“身份”映射实体 ID,Hibernate 将始终在您尝试持久化它时立即生成一个新 ID。您必须将世代切换为“已分配”以保留您的旧 ID。

【讨论】:

    【解决方案2】:

    如果你有类似的东西

    @Entity
    public class Project {
        @Id @GeneratedValue long id; // still set automatically
    
    }
    

    您必须从 id 字段中删除 @GeneratedValue 注释。否则 jpa 会在插入之前为 id 生成一个值。

    @Entity
    public class Project {
        @Id long id; // must be initialized by the application
         :
    }
    

    解决您的问题

    1. 创建一个包含所有映射定义的实体。
    2. 在没有@Generated 值注释的新类中创建一个 ID 字段。
    3. 将旧实体克隆到新实体。
    4. 坚持这个新实体。

    现在,如果您创建一个扩展实体的子类,那么整个 过程变得非常简单。

    此解决方案的示例代码

    现有实体

    @Entity
    @Table(name="EJB_PROJECT")
    public class OldEntity implements Serializable {
    
        @Id
        @Column(name="PROJECT_ID", primaryKey=true)
        @GeneratedValue
        Integer id;
    }
    

    新实体

    @Entity
    @Inheritance(strategy=SINGLE_TABLE)
    @Table(name="EJB_PROJECT")
    public class NewEntity extends OldEntity {
    
        @Id
        @Column(name="PROJECT_ID", primaryKey=true)
        Integer id;
    
        // Constructor to clone old entity's id
        public NewEnity(OldEntity old) {
            this.id = old.id;
        }
    }
    

    持久化代码

    em.persist(new NewEntity(oldEntity));
    

    【讨论】:

    • 有没有办法暂时做到这一点(我从另一个真正需要@GeneratedValue 的项目中导入@Entity 类)
    • @Mr.H.我已经用解决方案更新了我的答案。这个策略应该会奏效。
    • 好主意,它有效,但它不是我正在寻找的方式,我需要坚持大约 200 个实体。您的解决方案对我来说意味着 200 个子类。您是否有其他想法可以减少工作量。
    猜你喜欢
    • 2011-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-06
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 1970-01-01
    相关资源
    最近更新 更多