fel*_*gdr 10 java database sql-server hibernate jpa
我有一个表与一个简单的int id列在SQL Server中具有标识自动增量.
实体的Id用@Id和注释@GeneratedValue
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", length = 4, precision = 10, nullable = false)
private Integer id;
Run Code Online (Sandbox Code Playgroud)
在SQL Server中,该列已正确设置为Identity with Seed并且Increment等于1.
当我尝试持久化该实体的实例时,Hibernate尝试查询hibernate_sequence表以获取ID值.由于我没有在我的架构中创建该表,我收到一个错误:
could not read a hi value: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'MySchema.hibernate_sequence'
如果我将生成类型更改为IDENTITY,一切都按预期工作
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", length = 4, precision = 10, nullable = false)
private Integer id;
Run Code Online (Sandbox Code Playgroud)
我无法以这种方式更改它,因为我的应用程序将在MS SQL和ORACLE上运行,后者不支持自动增量列.
据我所知,如果底层数据库对它有支持,AUTO类型应该使用自动增量行为,所以我不知道为什么不工作.
更新:
我花了一些时间,但我能够准确理解发生了什么.
我正在使用具有以下行为的旧数据库:
以下是使用一些id生成策略的结果:
所以我需要弄清楚的是将该实体配置为:
当我需要插入依赖于主实体的实体(通过外键)时,这可能会导致Oracle出现严重问题,因为Hibernate不会知道"外部"触发器生成了哪个ID值.
Dan*_*uez 10
将此属性添加到我的persistence.xml文件中可修复此问题:
<property name="hibernate.id.new_generator_mappings" value="false" />
Run Code Online (Sandbox Code Playgroud)
Orcale 12c支持IDENTITY,SQL SERVER 2012支持SEQUENCES.我相信SEQUENCE总是比IDENTITY更好的选择.IDENTITY禁用批处理,SEQUENCES允许您提供优化程序,例如池化优化策略.
这是为配置的GenerationType值选择实际标识符生成器的方式:
switch ( generatorEnum ) {
case IDENTITY:
return "identity";
case AUTO:
return useNewGeneratorMappings
? org.hibernate.id.enhanced.SequenceStyleGenerator.class.getName()
: "native";
case TABLE:
return useNewGeneratorMappings
? org.hibernate.id.enhanced.TableGenerator.class.getName()
: MultipleHiLoPerTableGenerator.class.getName();
case SEQUENCE:
return useNewGeneratorMappings
? org.hibernate.id.enhanced.SequenceStyleGenerator.class.getName()
: "seqhilo";
}
Run Code Online (Sandbox Code Playgroud)
如果您使用新的标识符生成器:
properties.put("hibernate.id.new_generator_mappings","true");
AUTO实际上将使用SequenceStyleGenerator,并且数据库不支持序列,您最终会使用TABLE生成器(这是一个可移植的解决方案,但它的效率低于IDENTITY或SEQUENCE).
如果您使用遗留标识符生成器,则最终会使用"本机"生成策略,这意味着:
public Class getNativeIdentifierGeneratorClass() {
if ( supportsIdentityColumns() ) {
return IdentityGenerator.class;
}
else if ( supportsSequences() ) {
return SequenceGenerator.class;
}
else {
return TableHiLoGenerator.class;
}
}
Run Code Online (Sandbox Code Playgroud)如果要添加新的Oracle12gDialect并且它将支持IDENTITY,那么AUTO可能会切换到IDENTITY而不是SEQUENCE,可能会破坏您当前的期望.目前没有这样的方言,所以在Oracle上有SEQUENCE,在MSSQL中你有IDENTITY.
结论:
试试这样:
@Id
@GenericGenerator(name = "native_generator", strategy = "native")
@GeneratedValue(generator = "native_generator")
private Long id;
Run Code Online (Sandbox Code Playgroud)
如果旧系统使用表生成序列值,并且没有使用过hilo优化,则可以使用表标识符生成器:
@Id
@GeneratedValue(generator = "table", strategy=GenerationType.TABLE)
@TableGenerator(name = "table", allocationSize = 1
)
private Long id;
Run Code Online (Sandbox Code Playgroud)
您也可以使用JPA表生成器,只需确保配置正确的优化器.有关更多信息,请查看我的Hibernate教程
| 归档时间: |
|
| 查看次数: |
24686 次 |
| 最近记录: |