In Java, the standard approach for UUID v4 is still UUID.randomUUID(). That is the right default if you only need random UUIDs. Do not add a third-party dependency just to generate v4 unless your project already uses one for other UUID versions or shared utilities.
For JPA and Hibernate models, be explicit about how UUIDs are stored and mapped. If the database supports a native UUID type, use it. If not, choose a compact representation carefully. Letting every layer improvise its own string format and column type creates avoidable friction in queries, indexing, and data portability.
Generate the UUID in one place. In Java services, that often means the application service layer, the entity factory, or a dedicated ID abstraction. Avoid mixing app-generated UUIDs with database-generated IDs for the same entity type unless the design clearly calls for two different identifiers. Inconsistent generation rules usually create confusion in tests, logs, and integrations.
Use UUID objects in Java code where practical, and only convert to strings at the edges. That keeps the domain model clearer and avoids unnecessary format handling in the core of the application. Validate external UUID input at API boundaries instead of assuming every inbound string is well formed.
Finally, do not confuse “built in” with “best for every workload.” In Java, UUID.randomUUID() is easy. That does not settle the storage design. Keep the API convenience and the database consequences as two separate decisions.