---
# System prepended metadata

title: Proto Persistence

---

# Proto Persistence

## Protobuf
```protobuf=
syntax = "proto3";

package telos;

option go_package = "telos";
option java_package = "com.telos";
option java_multiple_files = true;

message Person {

  uint64 id = 1;
  string name = 2;
  string city = 3;
}
```
## pom.xml
```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.telos</groupId>
        <artifactId>platform</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>com.telos.platform</groupId>
    <artifactId>schema-repository</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>schema-repository</name>
    <description>schema-repository</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

```
## Domain
```java
package com.telos.platform.repository.domain;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

@Document
@Data
public class Person {

    @Transient
    private com.telos.Person personProto;

    @Id
    protected Long id;

    @Indexed
    protected String name;
    private byte[] proto;

    public Person() {
    }

    public Person(com.telos.Person personProto) {
        this.id = personProto.getId();
        this.name = personProto.getName();
        this.proto = personProto.toByteArray();
        System.out.println("Proto Constructor");
    }
}
```
## Repository
```java
package com.telos.platform.repository.repository;

import com.telos.platform.repository.domain.Person;
import org.springframework.data.mongodb.repository.MongoRepository;

import java.util.List;

public interface PersonRepository extends MongoRepository<Person, Long> {

    List<Person> findByName(String name);
}
```
## Entity Callback
```java
package com.telos.platform.repository.listener;

import com.telos.platform.repository.domain.Person;
import lombok.SneakyThrows;
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertCallback;
import org.springframework.stereotype.Component;

@Component
public class PersonEntityCallback implements BeforeConvertCallback<Person> {

    @SneakyThrows
    @Override
    public Person onBeforeConvert(Person entity, String collection) {
        byte[] bytes = entity.getProto();
        com.telos.Person person = com.telos.Person.parseFrom(bytes);
        entity.setPersonProto(person);
        return entity;
    }
}
```
## Test case
```java
package com.telos.platform.repository.repository;

import com.google.protobuf.InvalidProtocolBufferException;
import com.telos.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Optional;

@SpringBootTest
class PersonRepositoryTest {

    @Autowired
    private PersonRepository personRepository;

    @Test
    public void testSave() throws InvalidProtocolBufferException {
        Person.Builder personBuilder = Person.newBuilder();
        personBuilder.setId(100L);
        personBuilder.setName("Rajan" + System.currentTimeMillis());
        personBuilder.setCity("Delhi" + System.currentTimeMillis());
        Person personProto = personBuilder.build();

        com.telos.platform.repository.domain.Person person = new com.telos.platform.repository.domain.Person(personProto);
        com.telos.platform.repository.domain.Person savedPerson = personRepository.save(person);
        System.out.println("Saved Domain");
        System.out.println("Id : " + person.getId());
        System.out.println("Name : " + person.getName());
        System.out.println("Bytes : " + person.getProto().length);

        System.out.println("Proto");
        byte[] bytes = savedPerson.getProto();
        personProto = Person.parseFrom(bytes);
        System.out.println("Id : " + personProto.getId());
        System.out.println("Name : " + personProto.getName());
        System.out.println("City : " + personProto.getCity());
    }

    @Test
    public void testGet() throws InvalidProtocolBufferException {
        System.out.println("**** Before Find ***** ");
        Optional<com.telos.platform.repository.domain.Person> byId = personRepository.findById(100L);
        System.out.println("**** After Find ***** ");
        if(byId.isPresent()) {
            com.telos.platform.repository.domain.Person person = byId.get();
            System.out.println("**** Domain ***** ");
            System.out.println("Id : " + person.getId());
            System.out.println("Name : " + person.getName());

            System.out.println("****** Proto *******");
            byte[] bytes = person.getProto();
            System.out.println("bytes.length : " + bytes.length);
            Person personProto = Person.parseFrom(bytes);
            System.out.println("Id : " + personProto.getId());
            System.out.println("Name : " + personProto.getName());
            System.out.println("City : " + personProto.getCity());
            System.out.println("City : " + personProto.toByteArray().length);
        }
    }

}
```