Spring mvc autocomplete textbox - spring

I want to make a autocomplete textbox. I have an Entity Location
#Entity
public class Location {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int lId;
private String lName;
public Location() {
super();
}
public Location(int lId, String lName) {
super();
this.lId = lId;
this.lName = lName;
}
//getters and setters
It should be something like this
I have no idea how to complete this task. I have tried jQuery Autocomplite, but it wasn't success. Can anyone explaine me, how can i make it works.
I have already tried this solution. But it didn't help me. It doesnt work.

If you dont want to use a third-party library then use this: example
Else if you don't mind using third-party code, then you could use this one:
GlazedList implementation auto-completion.
You can install GlazedList on a JComboBox with only one line of Glazed code, like this:
JComboBox comboBox = new JComboBox();
Object[] elements = new Object[] {"name person", "name person", "name person", "name person"};
AutoCompleteSupport.install(comboBox, GlazedLists.eventListOf(elements));
Glazed Lists: source

Related

Spring: Handle child collection update the right way

Let's say that I manage an online shop. I want to be able to add and update products via a REST API.
The expected DTO would be something like this:
{
"id": 1,
"name": "iPhone 11 Pro",
"price": 999,
"pictures": [
{
"url": "http://image.com/image1.jpg",
"description": "image 1"
},
{
"url": "http://image.com/image2.jpg",
"description": "image 2"
}
]
}
Using JPA, this would require the 2 following entities:
#Entity
public class Product {
private Long id;
private String name;
private Integer price;
#OneToMany(mappedBy="product")
private List<ProductPicture> pictures;
}
#Entity
public class ProductPicture {
private Long id;
#ManyToOne
private Product product;
private String url;
private String description;
}
How to handle a product update? In all tutorials / sample codes I find, it's always a very basic example with a single entity having no collection.
I think about some options:
retrieve the product from DB, empty the "pictures" list and refill it, then save;
retrieve the product from DB, iterate over all pictures to find matches then remove/add what is needed, then save;
maybe that there is a Spring/Hibernate magic for handling this?
I don't like the 2 first ones.
I'm almost thinking to opt for a NoSQL database since it would be a lot easier for this use case... even if it's probably not a good reason.
Also, I'm not in favor of using a dedicated endpoint for this (like POST or DELETE on /products/1/pictures).
Could you please share a sample code to handle the update using Spring / Hibernate?
Thanks!
I finally ended up using the #Embeddable and #ElementCollection annotations that I didn't know, which looks to be a perfect fit for what I wanted to do.
#Entity
public class Product {
private Long id;
private String name;
private Integer price;
#ElementCollection(fetch = FetchType.EAGER)
private List<ProductPicture> pictures;
}
#Embeddable
public class ProductPicture {
private String url;
private String description;
}
This way the update is super-easy:
Product dbProduct = productRepository.findById(product.getId()).get();
// ...
dbProduct.setPictures(product.getPictures());
productRepository.save(dbProduct);

Cannot Query Neo4j Repositories

Hey everyone I am fairly new to Neo4j and am having an issue querying my repositories.
Repository is the follow:
public interface NodeOneRepository extends GraphRepository<NodeOne> {
List<NodeOne> findByNodeTwoNodeThreeAndActiveTrue(NodeThree nodeThree);
}
My entities are the following:
#NodeEntity(label = "NodeOne")
public class NodeOne {
#GraphId
private Long id;
private Boolean active = TRUE;
#Relationship(type = "IS_ON")
private NodeTwo nodeTwo;
}
#NodeEntity(label = "NodeTwo")
public class NodeTwo {
#GraphId
private Long id;
#Relationship(type = "CONTAINS", direction = "INCOMING")
private NodeThree nodeThree;
#Relationship(type = "IS_ON", direction = "INCOMING")
private List<NodeOne> nodeOnes = new ArrayList<>();
}
#NodeEntity(label = "NodeThree")
public class NodeThree {
#GraphId
private Long id;
#Relationship(type = "CONTAINS")
private List<NodeTwo> nodeTwos = new ArrayList<>();
}
Getters & Setters omitted. When I call the method I get an empty list. Is there something I am doing incorrectly?
You didn't describe exactly what you wanted to achieve, but I can see two problems:
Problem 1:
The current version of Spring Data Neo4j and OGM only allow nested finders, that is, finders that specify a relationship property, to one depth.
Supported
findByNodeTwoSomePropertyAndActiveTrue(String relatedNodePropertyValue)
Not Supported
findByNodeTwoNodeThree //Nesting relationships in finders is not supported
Problem 2:
Derived Finders Allow Matching Properties and Nested Properties. Not a whole instance of that class.
You can probably achieve what you would like using a custom query.
#Query("custom query here")
List<NodeOne> findByNodeTwoNodeThreeAndActiveTrue(NodeThree nodeThree);
If you need help to write a custom query, you can post another question or join the neo4j-users public slack channel.

Spring Data Rest save record with relation (foreign-key) in Java (repo.save())

I don't know how to save a record in SDR with a link to an existing table.
For example:
There is a lookup-table Flag and another table Account with name and n:1 relation to Flag-ID.
The IDs in Flag-table are already created.
#Entity
public class Account{
public Account(String name, Flag flag){
this.name = name;
this.flag = flag;
}
#Id
private int id;
#Column
private String name;
#ManyToOne
private Flag flag;
// Getter & Setter
}
#Entity
public class Flag{
public Flag(String title){
this.title = title;
}
#Id
private int id;
#Column
private String title;
// Getter & Setter
}
Now I want to add an account and link it to the flag-id like this:
AccountRepo accountRepo;
accountRepo.save(new Account("Name", 0));
But I declared an object in my account-function and if I want to execute the save-function, I have to add a flag-object like this:
accountRepo.save(new Account("Name", new Flag("title")));
However in this case, the framework will add a new Flag-record, what I don't want. I only want to link it.
So I need help for solving my problem.
Thanks!
Edit:
The two answers from #piotr-sołtysiak and #upesh-m helped and worked for me. Thanks for your help!
You can use 'merge' of hibernate, ie. entityManager.merge(new Account("Name", new Flag("title"))). But the Id of the Flag should be an existing Id , so that it just adds an entry to Account.
ie. If you already have a flag record existing in db with id = 1, and you want to add an account linked to this flag, then use entityManager.merge(new Account("Name", existingFlagObject)
Find desired flag entity using dedicated repository, e.g
Flag flag = flagRespository.findByTitle("title");
Set it in Account entity and save:
accountRepo.save(new Account("Name", flag));

How to properly apply PrePersist like logic using jpa/spring-boot

I have a very simple use case for the following model
#Entity
#Table(name='Foo')
class Foo {
#Id
String id = UUID.randomUUID()
String bar
Date foo_updated
}
I'd like to set the foo_updated value to new Date() when I see the incoming json payload has a value for "bar" (ie- this is a new value included in the POST/ a part of the PATCH update / included and proven to be different in a PUT)
I was hoping to simply apply the #PrePersist annotation on this model and add a simple conditional asking if "bar" was valid ...but quickly realized I wouldn't know if the value was "different" from what was in the db already (for the PATCH/PUT scenario).
I'm starting down the road of "add my own RestController" and apply this logic on the way in using the spring 4 ResponseEntity approach but ... I feel this might end up being a lot more work/more code to maintain.
As I'm new to spring-boot/spring-mvc/jpa I'm curious what other options I have and what the preferred approach would be for this seemingly "simple" requirement
Thanks for the help!
I came across this approach recently which involves recording the previous state on load. You now have access to the previous state after the new values are bound.
#Entity
#Table(name='Foo')
class Foo {
#Id
String id = UUID.randomUUID()
String bar
Date foo_updated
#Transient
private Foo previousState;
#PostLoad
private void setPreviousState(){
previousState = new Foo();
//copy the fields
}
}
However in your case can't you just do:
#Entity
#Table(name='Foo')
class Foo {
#Id
private String id = UUID.randomUUID()
private String bar
private Date lastUpdated;
public void setBar(String bar){
if(! this.bar.equals(bar){
lastUpdated = new Date();
}
}
}

Hibernate tuple criteria queries

I am trying to create a query using hibernate following the example given in section 9.2 of chapter 9
The difference with my attempt is I am using spring MVC 3.0. Here is my Address class along with the method i created.
#RooJavaBean
#RooToString
#RooEntity
#RooJson
public class Address {
#NotNull
#Size(min = 1)
private String street1;
#Size(max = 100)
private String street2;
private String postalcode;
private String zipcode;
#NotNull
#ManyToOne
private City city;
#NotNull
#ManyToOne
private Country country;
#ManyToOne
private AddressType addressType;
#Transient
public static List<Tuple> jqgridAddresses(Long pID){
CriteriaBuilder builder = Address.entityManager().getCriteriaBuilder();
CriteriaQuery<Tuple> criteria = builder.createTupleQuery();
Root<Address> addressRoot = criteria.from( Address.class );
criteria.multiselect(addressRoot.get("id"), addressRoot.get("street1"), addressRoot.get("street2"));
criteria.where(builder.equal(addressRoot.<Set<Long>>get("id"), pID));
return Address.entityManager().createQuery( criteria ).getResultList();
}
}
The method called jqgridAddresses above is the focus. I opted not to use the "Path" because when I say something like Path idPath = addressRoot.get( Address_.id ); as in section 9.2 of the documentation, the PathAddress_.id stuff produces a compilation error.
The method above returns an empty list of type Tuple as its size is zero even when it should contain something. This suggests that the query failed. Can someone please advise me.
OK so i made some minor adjustments to my logic which is specific to my project, however, the following approach worked perfectly. Hope it hepls someone in need !
#Transient
public static List<Tuple> jqgridPersons(Boolean isStudent, String column, String orderType, int limitStart, int limitAmount){
CriteriaBuilder builder = Person.entityManager().getCriteriaBuilder();
CriteriaQuery<Tuple> criteria = builder.createTupleQuery();
Root<Person> personRoot = criteria.from(Person.class );
criteria.select(builder.tuple(personRoot.get("id"), personRoot.get("firstName"), personRoot.get("lastName"), personRoot.get("dateOfBirth"), personRoot.get("gender"), personRoot.get("maritalStatus")));
criteria.where(builder.equal( personRoot.get("isStudent"), true));
if(orderType.equals("desc")){
criteria.orderBy(builder.desc(personRoot.get(column)));
}else{
criteria.orderBy(builder.asc(personRoot.get(column)));
}
return Address.entityManager().createQuery( criteria ).setFirstResult(limitStart).setMaxResults(limitAmount).getResultList();
}

Resources