How to Use @Id with String Type in JPA/Hibernate

How to use @Id with String Type in JPA / Hibernate?

If you don't specify an id generation strategy, Hibernate will use GenerationType.AUTO. This will result in any of

AUTO - either identity column, sequence or table depending on the
underlying DB.

If you look here, you'll notice all of those generate ids of type long, short or int, not of type String.

Say you wanted a String UUID as an id, you could use

@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
@Column(name = "PR_KEY")
private String prKey;

How to generate string id in hibernate like long?

@GeneratedValue(strategy = GenerationType.IDENTITY) cannot be used with String type. So, if you want to use String as ID, you have to assign it manually.

A possible solution is to have custom id generator:

@Id
@GenericGenerator(name = "sequence_id", strategy = "com.xyz.IdGenerator")
@GeneratedValue(generator = "sequence_id")
@Column(name="Id")
private String Id;

Id Generator class:

package com.xyz;

import java.io.Serializable;
import java.sql.*;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.IdentifierGenerator;

public class IdGenerator implements IdentifierGenerator{

@Override
public Serializable generate(SessionImplementor session, Object object)
throws HibernateException {

Connection connection = session.connection();

try {
Statement statement=connection.createStatement();

ResultSet rs=statement.executeQuery("select count(Id) from dbo.TableName");

if(rs.next())
{
int id=rs.getInt(1);
return new Integer(id).toString();
}
} catch (SQLException e) {

e.printStackTrace();
}

return null;
}

}

why I can't use string as id

The problem is that String username; is annotated with both @Id and @GeneratedValue. @Id means that is should be a primary key, fine it can be a String. But @GeneratedValue means that you want the system to automatically generate a new key when you create a new record. That's easy when the primary key is integer, all databases have a notion of sequence (even if the syntax is not always the same). But if you want String automatically generated keys, you will have do define your own custom generator.

Or if you have no reason for the @GeneratedValue annotation, simply remove it as suggested by Bohuslav Burghardt

xHow can I have @Id string for CrudRepository in Spring with Spring Data JPA?

You must change the type of the ID type parameter in the repository to match with the id attribute type on your entity.

From the Spring docs:

Interface Repository<T,ID>
Type Parameters:
T - the domain type the repository manages
ID - the type of the id of the entity the repository manages

Based on

@Entity // This tells Hibernate to make a table out of this class
@Table(name = "users")
public class XmppUser {
@Id
private java.lang.String username;
//...

}

It should be

public interface UserRepository extends CrudRepository<XmppUser, String> {
//..
}

See:

  • https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html#findById(ID)
  • https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/Repository.html

Hibernate Search returns a string type

I think it would be easier for you to switch to Spring Data JPA. Using that it would be easier for you to achieve the desired goal:

public interface PdfMapRepository extends JpaRepository<PdfMap, Integer> {

@Query("select pm.pdfField from PdfMap pf where pf.id = :id")
Optional<String> findPdfFieldByPdfMapId(Integer id);

}

Without Spring Data the same can be achieved with

TypedQuery<String> query = em.createQuery("select pm.pdfField from PdfMap pf where pf.id = :id", String.class);
List<String> results = query.getResultList();

Alternatively you can use Criteria API as

Session session = sessionFactory.openSession();

CriteriaQuery<Double> cr = cb.createQuery(String.class);
Root<PdfMap> root = cr.from(PdfMap.class);
cr.select(root.get("pdfField"));

Query<String> query = session.createQuery(cr);
List<String> formFields = query.getResultList();


Related Topics



Leave a reply



Submit