Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring boot JPA findByUuid

I want to query the database for a given UUID that is not the primary key.I cannot make it works:

Here is my Node class. My PK is a long auto increment and I have a field called uuid for store the UUID key generated when a new node is saved in the database.

Update: even if I get a node by id and then I use its node uuid to call the findByUuid function I am getting a null value

    Node n = nodeService.getNodeByNodeId(1L);
    return nodeService.getNodeByNodeUuid(n.getApiKey());

Node

@Entity
@Table(name="node")
public class Node {

@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.AUTO, generator = "node_seq")
@SequenceGenerator(name = "node_seq", sequenceName = "node_seq", allocationSize = 1)
private Long id;

@Column(name = "uuid", updatable = false, nullable = false, unique=true)
private UUID uuid;


public UUID getUuid() {
    return uuid;
}

public void setUuid(UUID uuid) {
    this.uuid = uuid;
}

@Column(name = "NAME", length = 50, unique = true)
@NotNull    
private String name;

@OneToMany(mappedBy="node", cascade=CascadeType.ALL)
private List<User> users;

public List<User> getUsers() {
    return users;
}

public void setUsers(List<User> users) {
    this.users = users;
}
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;
}

}

Controller

    @PreAuthorize("hasRole('MANAGER')")
    @RequestMapping(value="/node/{nodeUuidString}", method = RequestMethod.GET)
    public Node getNodeByUuid(@PathVariable UUID nodeUuidString) {
       return nodeService.getNodeByNodeUuid(nodeUuidString);
}

I also get the nodeUuidString as a String and then converted to UUID with:

UUID nodeUuid = UUID.fromString(nodeUuidString);

But it did not worked.

Service

    public Node getNodeByNodeUuid(UUID nodeUuid) {
       return nodeRepository.findOneByUuid(nodeUuid);
}

Repository

@Repository
public interface NodeRepository extends CrudRepository<Node, Long> {

Node findOneByUuid(UUID nodeUuid);

}

like image 873
dmance Avatar asked Jan 26 '18 10:01

dmance


3 Answers

Spring was creating the field in the database as binary(255)

The correct one is binary(16)

So, for get the query working I had to use this annotation on the entity definition:

@Column(name = "apiKey", updatable = false, nullable = false, unique=true, columnDefinition = "BINARY(16)")

like image 53
dmance Avatar answered Nov 09 '22 15:11

dmance


The reason behind it is that by default hibernate translates UUID into BINARY(255) 255 being the default length value. The size of UUID is actually BINARY(16). Thus causing in mismatch when they are compared.

The solution is to use specify the length for column as follows

@Column(length=16)
UUID uuid;

Note: If you are using sql database that's not generated by the spring, you will have to alter the id column

alter table table_name modify column uuid binary(16);
like image 23
Sudip Bhattarai Avatar answered Nov 09 '22 15:11

Sudip Bhattarai


Just write your own query if nothing works:

@Query("SELECT n FROM Node n WHERE n.uuid= ?1")
Node findOneByUuid(UUID nodeUuid);
like image 33
Den B Avatar answered Nov 09 '22 13:11

Den B