How to annotate MYSQL autoincrement field with JPA annotations
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
For a MySQL AUTO_INCREMENT primary key, the usual JPA mapping is @Id together with @GeneratedValue(strategy = GenerationType.IDENTITY). That tells the persistence provider that the database, not the application, is responsible for generating the identifier during insert.
The Basic Mapping
Here is the common entity definition.
GenerationType.IDENTITY is the important part. It maps naturally to MySQL's auto-increment behavior, where the row is inserted first and the database returns the generated key.
Why IDENTITY Is the Right Strategy for MySQL Auto-Increment
JPA offers several generation strategies, but they are not interchangeable.
- '
IDENTITY: the database generates the key during insert' - '
SEQUENCE: for databases with sequence objects' - '
TABLE: uses a separate table to emulate sequence generation' - '
AUTO: lets the provider choose'
For a MySQL column defined with AUTO_INCREMENT, IDENTITY is the explicit and correct choice. It matches the underlying database feature directly instead of depending on provider inference.
Let the Database Generate the Value
Do not set the id field manually before persisting the entity.
After persist and flush, JPA obtains the generated key from MySQL and populates the entity field. If you assign the primary key yourself while also declaring IDENTITY, you are mixing two incompatible strategies.
Wrapper Types Are Usually Better Than Primitives
Use Long or Integer instead of primitive long or int for generated IDs. A nullable wrapper cleanly represents the pre-persist state where the entity has no database identity yet.
With a primitive type, 0 can be confused with a meaningful application value even though the row has not been inserted yet.
Match the Database Schema
Your MySQL schema should define the primary key column accordingly.
If the table is not actually configured with AUTO_INCREMENT, the JPA annotation alone will not manufacture the right database behavior. The entity mapping and schema must agree.
One Important Behavior Difference
IDENTITY generation usually means the insert must happen before the identifier is known. That can affect batching behavior in some JPA providers. It is not usually a correctness problem, but it matters when people compare IDENTITY with sequence-based strategies on other databases.
For MySQL auto-increment, that tradeoff is normal and expected.
Common Pitfalls
- Using
GenerationType.AUTOand assuming it will always choose the intended MySQL behavior. - Setting the ID field manually even though the database is supposed to generate it.
- Using
SEQUENCEwith MySQL auto-increment tables, which does not match the database model. - Declaring the JPA annotations correctly while forgetting to define
AUTO_INCREMENTin the actual schema. - Using a primitive ID type when a nullable wrapper would better represent the entity lifecycle.
Summary
- Map a MySQL auto-increment primary key with
@Idand@GeneratedValue(strategy = GenerationType.IDENTITY). - Let MySQL generate the identifier during insert.
- Prefer
LongorIntegerover primitive numeric types for generated IDs. - Keep the JPA mapping and database schema consistent.
- '
IDENTITYis the standard explicit strategy for MySQLAUTO_INCREMENTcolumns.'

