Java - JPA - 生成器 - @SequenceGenerator
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2595124/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java - JPA - Generators - @SequenceGenerator
提问by Yatendra Goel
I am learning JPA and have confusion in the @SequenceGenerator
annotation.
我正在学习 JPA 并且在@SequenceGenerator
注释中有混淆。
To my understanding, it automatically assigns a value to numeric identity fields/properties of an entity.
据我了解,它会自动为实体的数字标识字段/属性分配一个值。
Q1.Does this sequence generator make use of the database's increasing numeric value generating capability or generates the number on it's own?
一季度。这个序列生成器是利用数据库不断增加的数值生成能力还是自己生成数字?
Q2.If JPA uses database auto increment feature, then will it work with datastores that don't have auto increment feature?
Q2。如果 JPA 使用数据库自动增量功能,那么它是否适用于没有自动增量功能的数据存储?
Q3.If JPA generate numeric value on his own, then how does the JPA implementation know which value to generate next? Does it consult with the database first to see what value was stored last in order to generate the value (last + 1)?
Q3。如果 JPA 自己生成数值,那么 JPA 实现如何知道接下来生成哪个值?它是否首先咨询数据库以查看最后存储了什么值以生成值(last + 1)?
Q4.第 4 季度。还请一些线索
sequenceName
sequenceName
和allocationSize
allocationSize
性能的@SequenceGenerator
@SequenceGenerator
注解。回答by Kevin Crowell
sequenceName
is the name of the sequence in the DB. This is how you specify a sequence that already exists in the DB. If you go this route, you have to specify the allocationSize
which needs to be the same value that the DB sequence uses as its "auto increment".
sequenceName
是数据库中序列的名称。这是您指定数据库中已存在的序列的方式。如果你走这条路,你必须指定allocationSize
哪个需要与数据库序列用作其“自动增量”的值相同。
Usage:
用法:
@GeneratedValue(generator="my_seq")
@SequenceGenerator(name="my_seq",sequenceName="MY_SEQ", allocationSize=1)
If you want, you can let it create a sequence for you. But to do this, you must use SchemaGeneration to have it created. To do this, use:
如果需要,您可以让它为您创建一个序列。但是要做到这一点,您必须使用 SchemaGeneration 来创建它。为此,请使用:
@GeneratedValue(strategy=GenerationType.SEQUENCE)
Also, you can use the auto-generation, which will use a table to generate the IDs. You must also use SchemaGeneration at some point when using this feature, so the generator table can be created. To do this, use:
此外,您可以使用自动生成,它将使用一个表来生成 ID。使用此功能时,您还必须在某些时候使用 SchemaGeneration,以便可以创建生成器表。为此,请使用:
@GeneratedValue(strategy=GenerationType.AUTO)
回答by Whome
I have MySQL schema with autogen values. I use strategy=GenerationType.IDENTITY
tag and seems to work fine in MySQL I guess it should work most db engines as well.
我有带有 autogen 值的 MySQL 模式。我使用strategy=GenerationType.IDENTITY
标签并且似乎在 MySQL 中工作正常我想它也应该适用于大多数数据库引擎。
CREATE TABLE user (
id bigint NOT NULL auto_increment,
name varchar(64) NOT NULL default '',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
User.java
:
User.java
:
// mark this JavaBean to be JPA scoped class
@Entity
@Table(name="user")
public class User {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private long id; // primary key (autogen surrogate)
@Column(name="name")
private String name;
public long getId() { return id; }
public void setId(long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name=name; }
}
回答by Edy Aguirre
I use this and it works right
我用这个,它工作正常
@Id
@GeneratedValue(generator = "SEC_ODON", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name = "SEC_ODON", sequenceName = "SO.SEC_ODON",allocationSize=1)
@Column(name="ID_ODON", unique=true, nullable=false, precision=10, scale=0)
public Long getIdOdon() {
return this.idOdon;
}
回答by rk1891
Even though this question is very old and I stumbled upon it for my own issues with JPA 2.0 and Oracle sequences.
尽管这个问题已经很老了,而且我偶然发现了它是因为我自己在 JPA 2.0 和 Oracle 序列方面的问题。
Want to share my research on some of the things -
想分享我对一些事情的研究 -
Relationship between @SequenceGenerator(allocationSize)of GenerationType.SEQUENCEand INCREMENT BYin database sequence definition
数据库序列定义中GenerationType.SEQUENCE的@SequenceGenerator(allocationSize)和INCREMENT BY的关系
Make sure @SequenceGenerator(allocationSize)is set to same value as INCREMENT BYin Database sequence definition to avoid problems (the same applies to the initial value).
确保@SequenceGenerator(allocationSize)设置为与数据库序列定义中的INCREMENT BY相同的值以避免出现问题(同样适用于初始值)。
For example, if we define the sequence in database with a INCREMENT BY value of 20, set the allocationsize in SequenceGenerator also to 20. In this case the JPA will not make a call to database until it reaches the next 20 mark while it increments each value by 1 internally. This saves database calls to get the next sequence number each time. The side effect of this is - Whenever the application is redeployed or the server is restarted in between, it'll call database to get the next batch and you'll see jumps in the sequence values. Also we need to make sure the database definition and the application setting to be in-sync which may not be possible all the time as both of them are managed by different groups and you can quickly lose control of. If database value is less than the allocationsize, you'll see PrimaryKey constraint errors due to duplicate values of Id. If the database value is higher than the allocationsize, you'll see jumps in the values of Id.
例如,如果我们将数据库中的序列定义为 INCREMENT BY 值为 20,则将 SequenceGenerator 中的 allocationsize 也设置为 20。在这种情况下,JPA 将不会调用数据库,直到它达到下一个 20 标记,同时它会增加每个内部值加 1。这节省了每次获取下一个序列号的数据库调用。这样做的副作用是 - 每当应用程序被重新部署或服务器在两者之间重新启动时,它都会调用数据库来获取下一批,你会看到序列值的跳跃。此外,我们需要确保数据库定义和应用程序设置同步,这可能无法始终实现,因为它们都由不同的组管理,您可能很快就会失去控制。如果数据库值小于分配大小,你 由于 Id 的重复值,将看到 PrimaryKey 约束错误。如果数据库值高于分配大小,您将看到 Id 值的跳跃。
If the database sequence INCREMENT BY is set to 1 (which is what DBAs generally do), set the allocationSize as also 1 so that they are in-sync but the JPA calls database to get next sequence number each time.
如果数据库序列 INCREMENT BY 设置为 1(这是 DBA 通常所做的),则将 allocationSize 也设置为 1,以便它们同步,但 JPA 每次都会调用数据库来获取下一个序列号。
If you don't want the call to database each time, use GenerationType.IDENTITYstrategy and have the @Id value set by database trigger. With GenerationType.IDENTITYas soon as we call em.persistthe object is saved to DB and a value to id is assigned to the returned object so we don't have to do a em.mergeor em.flush. (This may be JPA provider specific..Not sure)
如果您不想每次都调用数据库,请使用GenerationType.IDENTITY策略并通过数据库触发器设置 @Id 值。使用GenerationType.IDENTITY,只要我们调用em.persist对象就被保存到数据库中,并且 id 的值被分配给返回的对象,因此我们不必执行em.merge或em.flush。(这可能是特定于 JPA 提供程序的......不确定)
Another important thing -
还有一件很重要的事——
JPA 2.0 automatically runs ALTER SEQUENCEcommand to sync the allocationSize and INCREMENT BY in database sequence. As mostly we use a different Schema name(Application user name) rather than the actual Schema where the sequence exists and the application user name will not have ALTER SEQUENCE privileges, you might see the below warning in the logs -
JPA 2.0 自动运行ALTER SEQUENCE命令以同步数据库序列中的 allocationSize 和 INCREMENT BY。由于大多数情况下我们使用不同的架构名称(应用程序用户名)而不是序列存在的实际架构,并且应用程序用户名没有 ALTER SEQUENCE 权限,您可能会在日志中看到以下警告 -
000004c1 Runtime W CWWJP9991W: openjpa.Runtime: Warn: Unable to cache sequence values for sequence "RECORD_ID_SEQ". Your application does not have permission to run an ALTER SEQUENCE command. Ensure that it has the appropriate permission to run an ALTER SEQUENCE command.
000004c1 运行时 W CWWJP9991W:openjpa.Runtime:警告:无法缓存序列“RECORD_ID_SEQ”的序列值。您的应用程序无权运行 ALTER SEQUENCE 命令。确保它具有运行 ALTER SEQUENCE 命令的适当权限。
As the JPA could not alter the sequence, JPA calls database everytime to get next sequence number irrespective of the value of @SequenceGenerator.allocationSize. This might be a unwanted consequence which we need to be aware of.
由于 JPA 无法更改序列,因此无论 @SequenceGenerator.allocationSize 的值如何,JPA 每次都会调用数据库来获取下一个序列号。这可能是我们需要注意的不良后果。
To let JPA not to run this command, set this value - in persistence.xml. This ensures that JPA will not try to run ALTER SEQUENCE command. It writes a different warning though -
要让 JPA 不运行此命令,请在 persistence.xml 中设置此值。这确保 JPA 不会尝试运行 ALTER SEQUENCE 命令。虽然它写了一个不同的警告 -
00000094 Runtime W CWWJP9991W: openjpa.Runtime: Warn: The property "openjpa.jdbc.DBDictionary=disableAlterSeqenceIncrementBy" is set to true. This means that the 'ALTER SEQUENCE...INCREMENT BY' SQL statement will not be executed for sequence "RECORD_ID_SEQ". OpenJPA executes this command to ensure that the sequence's INCREMENT BY value defined in the database matches the allocationSize which is defined in the entity's sequence. With this SQL statement disabled, it is the responsibility of the user to ensure that the entity's sequence definition matches the sequence defined in the database.
00000094 运行时 W CWWJP9991W:openjpa.Runtime:警告:属性“openjpa.jdbc.DBDictionary=disableAlterSeqenceIncrementBy”设置为 true。这意味着不会为序列“RECORD_ID_SEQ”执行“ALTER SEQUENCE...INCREMENT BY”SQL 语句。OpenJPA 执行此命令以确保数据库中定义的序列的 INCREMENT BY 值与实体序列中定义的 allocationSize 相匹配。禁用此 SQL 语句后,用户有责任确保实体的序列定义与数据库中定义的序列相匹配。
As noted in the warning, important here is we need to make sure @SequenceGenerator.allocationSize and INCREMENT BY in database sequence definition are in sync including the default value of @SequenceGenerator(allocationSize) which is 50. Otherwise it'll cause errors.
正如警告中所指出的,这里重要的是我们需要确保数据库序列定义中的@SequenceGenerator.allocationSize 和INCREMENT BY 是同步的,包括@SequenceGenerator(allocationSize) 的默认值是50。否则会导致错误。