{"id":2168,"date":"2016-05-30T07:54:06","date_gmt":"2016-05-30T07:54:05","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2168"},"modified":"2016-05-30T07:54:06","modified_gmt":"2016-05-30T07:54:05","slug":"vaadin-couchbase-crud-sample","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/","title":{"rendered":"Vaadin\/Couchbase CRUD Sample"},"content":{"rendered":"<p>Last week while I was at JFokus I met <a href=\"https:\/\/twitter.com\/mattitahvonen\">Matti Tahvonen<\/a>, he works at <a href=\"https:\/\/vaadin.com\/home\">Vaadin<\/a>. They have been proposing an open source web framework for rich Internet applications in Java for years and do it really well. I am personally really happy to write a full web modern application just in Java.<\/p>\n<p>We took 10 minutes to have a working Vaadin CRUD sample storing object in Couchbase. The result is available on <a href=\"https:\/\/github.com\/ldoguin\/couchbase-vaadin-spring-data-example\">Github<\/a>. Since then I also migrated a JPA based sample also available <a href=\"https:\/\/github.com\/ldoguin\/spring-data-vaadin-crud\">here<\/a>. You can see how very little work it requires and how easy it is to go from JPA to Couchbase with the <a href=\"https:\/\/github.com\/ldoguin\/spring-data-vaadin-crud\/commit\/d811d560d68fc37906b85a49a50fd1512108a001\">diff<\/a>.<\/p>\n<h2>Spring Data Couchbase meet Vaadin<\/h2>\n<h3>Generate the Project<\/h3>\n<p>The first step when starting a Spring project is to go on <a href=\"https:\/\/start.spring.io\/\">Spring Initializr<\/a>. Here you can select the version and dependencies you want for your project. Select\u00a0Spring Boot version 1.4.0(SNAPSHOT) and add\u00a0Vaadin and Couchbase as dependencies.<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2016\/february\/vaadin-couchbase-crud-sample\/vaadincouchbasecrud.png\" \/><\/p>\n<p>Now you can generate the project and import it as a Maven project in your editor of choice.<\/p>\n<h3>Basic Person Entity CRUD<\/h3>\n<p>This CRUD sample is going to store <strong>Customer<\/strong> objects. A customer has an <em>id<\/em>, a <em>firstName<\/em> and a <em>lastName<\/em>. Also, the last name must not be null. To express this as an entity, you just have to add the <strong>@Document<\/strong> annotation on the class, <strong>@Id<\/strong> annotation on the field to be used as Couchbase key, generate getters and setters and you are done. To express the not null constraints, we can simply use the Java validation annotations <strong>@NotNull.<\/strong> To make sure it&apos;s picked up when writing the entity, we&apos;ll need to declare a validator bean.<\/p>\n<pre>\n<code>package hello;\n\nimport java.util.Objects;\nimport java.util.UUID;\n\nimport javax.validation.constraints.NotNull;\n\nimport org.springframework.data.couchbase.core.mapping.Document;\n\nimport com.couchbase.client.java.repository.annotation.Id;\n\n@Document\npublic class Customer {\n\n    @Id\n    private String id = UUID.randomUUID().toString();\n\n    private String firstName;\n\n    @NotNull\n    private String lastName;\n\n    protected Customer() {\n    }\n\n    public Customer(String firstName, String lastName) {\n        this.firstName = firstName;\n        this.lastName = lastName;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public void setId(String id) {\n        this.id = id;\n    }\n\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n    }\n\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n\n    @Override\n    public String toString() {\n        return String.format(\"Customer[id=%s, firstName=&apos;%s&apos;, lastName=&apos;%s&apos;]\", id, firstName, lastName);\n    }\n\n    @Override\n    public int hashCode() {\n        int hash = 7;\n        hash = 37 * hash + Objects.hashCode(this.id);\n        return hash;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj) {\n            return true;\n        }\n        if (obj == null) {\n            return false;\n        }\n        if (getClass() != obj.getClass()) {\n            return false;\n        }\n        final Customer other = (Customer) obj;\n        return Objects.equals(this.id, other.id);\n    }\n\n}\n<\/code><\/pre>\n<h3>The Customer Repository<\/h3>\n<p>Once you have define an entity, you need to create the associated repository. Create an interface that extends the <strong>CouchbasePagingAndSortingRepository<\/strong>. This repository handles <strong>Customer<\/strong> entities with a String as key.<\/p>\n<p>I have redefined the <em>findAll<\/em> method to return a <strong>List<\/strong> instead of an <strong>Iterable<\/strong> as it plays better with Vaadin structures. The <em>findAll<\/em> method is backed up by a View. To have your views defined automatically you can add the<strong> @ViewIndexed <\/strong>annotation. You also need to make sure you have set the <em>spring.data.couchbase.auto-index<\/em> property to true in your <em>application.properties<\/em> file.<\/p>\n<p>I also added a <em>findByLastName(String lastName) <\/em>method. Based on the method name, the appropriate N1QL query will be automatically generated. But to execute N1Ql query, you need a primary index. Which can also be generated automatically through the <strong>@N1QLPrimaryIndexed<\/strong> annotation.<\/p>\n<pre>\n<code>package hello;\n\nimport java.util.List;\n\nimport org.springframework.data.couchbase.core.query.N1qlPrimaryIndexed;\nimport org.springframework.data.couchbase.core.query.ViewIndexed;\nimport org.springframework.data.couchbase.repository.CouchbasePagingAndSortingRepository;\n\n@ViewIndexed(designDoc = \"customer\")\n@N1qlPrimaryIndexed\npublic interface CustomerRepository extends CouchbasePagingAndSortingRepository<Customer, String> {\n\n    List<Customer> findAll();\n\n    List<Customer> findByLastName(String lastName);\n\n}\n<\/code><\/pre>\n<h3>Configuration<\/h3>\n<p>I am using spring spring-boot-starter-data-couchbase. It provides autoconfiguration. This autoconfiguration can be activated by setting the <em>spring.couchbase.bootstrap-hosts<\/em> property. So far my <em>application.properties<\/em> looks like this:<\/p>\n<p>\u00a0<\/p>\n<pre>\n<code>spring.couchbase.bootstrap-hosts=localhost\nspring.data.couchbase.auto-index=true\n<\/code><\/pre>\n<p>\u00a0<\/p>\n<h3>Create a Customer<\/h3>\n<p>Now I have everything I need to save a <strong>Customer<\/strong> Entity in Couchbase. We can try this easily with a <strong>CommandLineRunner<\/strong>:<\/p>\n<pre>\n<code>@SpringBootApplication\npublic class Application {\n\n    private static final Logger log = LoggerFactory.getLogger(Application.class);\n\n    public static void main(String[] args) {\n        SpringApplication.run(Application.class);\n    }\n\n    @Bean\n    public CommandLineRunner loadData(CustomerRepository repository) {\n        return (args) -> {\n            repository.save(new Customer(null, \"Dessler\"));\n        };\n    }\n\n    @Bean\n    public Validator validator() {\n        return new LocalValidatorFactoryBean();\n    }\n}\n<\/code><\/pre>\n<p>You&apos;ll notice that I have also added the validator bean previsouly mentionned. It uses a <strong><a href=\"https:\/\/docs.spring.io\/spring-data\/couchbase\/docs\/current\/api\/index.html?org\/springframework\/data\/couchbase\/core\/mapping\/event\/ValidatingCouchbaseEventListener.html\">ValidatingCouchbaseEventListener<\/a><\/strong> declared automatically by the spring boot auto-config.<\/p>\n<h3>Using Vaadin for UI<\/h3>\n<p>The backend is ready, we can start thinking about the frontend. I want a basic CRUD app that will show a list of Customer, the ability to add, edit or remove elements of the list. Here&apos;s a screenshot:<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2016\/february\/vaadin-couchbase-crud-sample\/vaadincrudui.png\" \/><\/p>\n<p>To Build this we start by creating a form that allow the user to enter a first name and a last name. Create a class that extends an <strong>AbstractForm<\/strong> of <strong>Customer<\/strong>. This class is not available in Vaadin Core, so we need to add <a href=\"https:\/\/vaadin.com\/directory#!addon\/viritin\">Viritin<\/a>.<\/p>\n<blockquote><p>Viritin is a server side enhancement library for Vaadin. It fixes some bad defaults in the core framework and provides more fluent and intelligent API for existing components. It also provides several major enhancements to databinding and provides completely new components made with server side composition (no widgetset is needed).<\/p><\/blockquote>\n<p>And yes it provides the <strong>AbstractForm<\/strong> class that is neatly integrated with Spring Data and validators. We need to edit the <em>firstName<\/em> and <em>lastName<\/em> fields of the <strong>Customer<\/strong> class, so we define two text fields called <em>firstName<\/em> and <em>lastName<\/em>. They have to have the same name as your Customer field. What is also great about this component is that it will pickup the validation annotation on your entity. This way you get automatic validation on the client and on the server. And it supports more complex annotations thanl<strong style=\"line-height: 20.8px;\">@NotNull<\/strong><span style=\"line-height: 1.6em;\">\u00a0like <strong>@Size <\/strong>or <strong>@Pattern<\/strong>.<\/span><\/p>\n<pre>\n<code>package hello;\n\nimport org.vaadin.viritin.form.AbstractForm;\nimport org.vaadin.viritin.layouts.MFormLayout;\n\nimport com.vaadin.spring.annotation.SpringComponent;\nimport com.vaadin.spring.annotation.UIScope;\nimport com.vaadin.ui.Component;\nimport com.vaadin.ui.TextField;\n\n@SpringComponent\n@UIScope\npublic class CustomerEditor extends AbstractForm<Customer> {\n\n    \/* Fields to edit properties in Customer entity *\/\n    TextField firstName = new TextField(\"First name\");\n    TextField lastName = new TextField(\"Last name\");\n\n    public CustomerEditor() {\n        setVisible(false);\n    }\n\n    @Override\n    protected Component createContent() {\n        return new MFormLayout(firstName, lastName, getToolbar());\n    }\n\n}\n<\/code><\/pre>\n<p>Now that the form is ready we can build the full UI displaying the table grid. This will be the main component of your Vaadin application, the main web page. Since the <strong>CustomerRepository<\/strong> and the <strong>CustomerEditor<\/strong> are Spring beans, we can inject them direclty in the constructor. If you are familiar with writing Java UI, the commented code below should be straight forward.<\/p>\n<pre>\n<code>package hello;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.vaadin.viritin.fields.MTable;\nimport org.vaadin.viritin.layouts.MVerticalLayout;\n\nimport com.vaadin.annotations.Theme;\nimport com.vaadin.server.FontAwesome;\nimport com.vaadin.server.VaadinRequest;\nimport com.vaadin.spring.annotation.SpringUI;\nimport com.vaadin.ui.Button;\nimport com.vaadin.ui.UI;\n\n@SpringUI\n@Theme(\"valo\")\npublic class VaadinUI extends UI {\n\n    private final CustomerRepository repo;\n\n    private final CustomerEditor editor;\n\n    private final MTable<Customer> grid;\n\n    private final Button addNewBtn;\n\n    @Autowired\n    public VaadinUI(CustomerRepository repo, CustomerEditor editor) {\n        this.repo = repo;\n        this.editor = editor;\n        this.grid = new MTable<>(Customer.class).withProperties(\"id\", \"firstName\", \"lastName\").withHeight(\"300px\");\n        this.addNewBtn = new Button(\"New customer\", FontAwesome.PLUS);\n    }\n\n    @Override\n    protected void init(VaadinRequest request) {\n        \/\/ Connect selected Customer to editor or hide if none is selected\n        grid.addMValueChangeListener(e -> {\n            if (e.getValue() == null) {\n                editor.setVisible(false);\n            } else {\n                editor.setEntity(e.getValue());\n            }\n        });\n\n        \/\/ Instantiate and edit new Customer the new button is clicked\n        addNewBtn.addClickListener(e -> editor.setEntity(new Customer(\"\", \"\")));\n\n        \/\/ Listen changes made by the editor, refresh data from backend\n        editor.setSavedHandler(customer -> {\n            repo.save(customer);\n            listCustomers();\n            editor.setVisible(false);\n        });\n\n        editor.setResetHandler(customer -> {\n            editor.setVisible(false);\n            listCustomers();\n        });\n\n        editor.setDeleteHandler(customer -> {\n            repo.delete(customer);\n            listCustomers();\n        });\n\n        \/\/ Initialize listing\n        listCustomers();\n\n        \/\/ build layout\n            setContent(new MVerticalLayout(addNewBtn, grid, editor));\n        }\n\n        private void listCustomers() {\n            grid.setBeans(repo.findAll());\n        }\n\n    }\n<\/code><\/pre>\n<p>And then you are all set, all you have to do is run this as a usual Java Spring Boot application. \u00a0So that was pretty easy huh?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last week while I was at JFokus I met Matti Tahvonen, he works at Vaadin. They have been proposing an open source web framework for rich Internet applications in Java for years and do it really well. I am personally [&hellip;]<\/p>\n","protected":false},"author":49,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1815,1818],"tags":[1595,1594],"ppma_author":[9023],"class_list":["post-2168","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-java","tag-spring-data-couchbase","tag-vaadin"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Vaadin\/Couchbase CRUD Sample - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Vaadin\/Couchbase CRUD Sample\" \/>\n<meta property=\"og:description\" content=\"Last week while I was at JFokus I met Matti Tahvonen, he works at Vaadin. They have been proposing an open source web framework for rich Internet applications in Java for years and do it really well. I am personally [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-05-30T07:54:05+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1800\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Laurent Doguin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ldoguin\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"unstructured.io\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/vaadin-couchbase-crud-sample\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/vaadin-couchbase-crud-sample\\\/\"},\"author\":{\"name\":\"Laurent Doguin\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/c0aa9b8f1ed51b7a9e2f7cb755994a5e\"},\"headline\":\"Vaadin\\\/Couchbase CRUD Sample\",\"datePublished\":\"2016-05-30T07:54:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/vaadin-couchbase-crud-sample\\\/\"},\"wordCount\":820,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/vaadin-couchbase-crud-sample\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"keywords\":[\"spring-data-couchbase\",\"vaadin\"],\"articleSection\":[\"Best Practices and Tutorials\",\"Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/vaadin-couchbase-crud-sample\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/vaadin-couchbase-crud-sample\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/vaadin-couchbase-crud-sample\\\/\",\"name\":\"Vaadin\\\/Couchbase CRUD Sample - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/vaadin-couchbase-crud-sample\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/vaadin-couchbase-crud-sample\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2016-05-30T07:54:05+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/vaadin-couchbase-crud-sample\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/vaadin-couchbase-crud-sample\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/vaadin-couchbase-crud-sample\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/vaadin-couchbase-crud-sample\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Vaadin\\\/Couchbase CRUD Sample\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/admin-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/c0aa9b8f1ed51b7a9e2f7cb755994a5e\",\"name\":\"Laurent Doguin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g12929ce99397769f362b7a90d6b85071\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g\",\"caption\":\"Laurent Doguin\"},\"description\":\"Laurent is a nerdy metal head who lives in Paris. He mostly writes code in Java and structured text in AsciiDoc, and often talks about data, reactive programming and other buzzwordy stuff. He is also a former Developer Advocate for Clever Cloud and Nuxeo where he devoted his time and expertise to helping those communities grow bigger and stronger. He now runs Developer Relations at Couchbase.\",\"sameAs\":[\"https:\\\/\\\/x.com\\\/ldoguin\"],\"honorificPrefix\":\"Mr\",\"birthDate\":\"1985-06-07\",\"gender\":\"male\",\"award\":[\"Devoxx Champion\",\"Couchbase Legend\"],\"knowsAbout\":[\"Java\"],\"knowsLanguage\":[\"English\",\"French\"],\"jobTitle\":\"Director Developer Relation & Strategy\",\"worksFor\":\"Couchbase\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/author\\\/laurent-doguin\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Vaadin\/Couchbase CRUD Sample - The Couchbase Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/","og_locale":"en_US","og_type":"article","og_title":"Vaadin\/Couchbase CRUD Sample","og_description":"Last week while I was at JFokus I met Matti Tahvonen, he works at Vaadin. They have been proposing an open source web framework for rich Internet applications in Java for years and do it really well. I am personally [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/","og_site_name":"The Couchbase Blog","article_published_time":"2016-05-30T07:54:05+00:00","og_image":[{"width":1800,"height":630,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png","type":"image\/png"}],"author":"Laurent Doguin","twitter_card":"summary_large_image","twitter_creator":"@ldoguin","twitter_misc":{"Written by":"unstructured.io","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/"},"author":{"name":"Laurent Doguin","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c0aa9b8f1ed51b7a9e2f7cb755994a5e"},"headline":"Vaadin\/Couchbase CRUD Sample","datePublished":"2016-05-30T07:54:05+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/"},"wordCount":820,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["spring-data-couchbase","vaadin"],"articleSection":["Best Practices and Tutorials","Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/","url":"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/","name":"Vaadin\/Couchbase CRUD Sample - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2016-05-30T07:54:05+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/vaadin-couchbase-crud-sample\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Vaadin\/Couchbase CRUD Sample"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c0aa9b8f1ed51b7a9e2f7cb755994a5e","name":"Laurent Doguin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g12929ce99397769f362b7a90d6b85071","url":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g","caption":"Laurent Doguin"},"description":"Laurent is a nerdy metal head who lives in Paris. He mostly writes code in Java and structured text in AsciiDoc, and often talks about data, reactive programming and other buzzwordy stuff. He is also a former Developer Advocate for Clever Cloud and Nuxeo where he devoted his time and expertise to helping those communities grow bigger and stronger. He now runs Developer Relations at Couchbase.","sameAs":["https:\/\/x.com\/ldoguin"],"honorificPrefix":"Mr","birthDate":"1985-06-07","gender":"male","award":["Devoxx Champion","Couchbase Legend"],"knowsAbout":["Java"],"knowsLanguage":["English","French"],"jobTitle":"Director Developer Relation & Strategy","worksFor":"Couchbase","url":"https:\/\/www.couchbase.com\/blog\/author\/laurent-doguin\/"}]}},"acf":[],"authors":[{"term_id":9023,"user_id":49,"is_guest":0,"slug":"laurent-doguin","display_name":"Laurent Doguin","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/2168","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/49"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=2168"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/2168\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=2168"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=2168"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=2168"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=2168"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}