I am using spring-cloud-gcp-starter-data-firestore for accessing Google Cloud Firestore in my Java Spring application.
Currently, my entity looks like this:
public class Subscription {
public String userId;
public String companyId;
// other properties
}
However, I obtain the userId and companyId via a reactor.core.publisher.Mono in org.springframework.security.core.context.ReactiveSecurityContextHolder.
How can I persist both properties which are nested inside Monos without resorting to Mono#block?
I am now using Mono#zipWith to combine both Monos. Then I am creating the entity inside Mono#flatMap.
service.getCompanyId()
.zipWith(service.getUserId())
.flatMap(objects -> createEntity(objects.getT1(), objects.getT2()))
I suggest following the tutorial in the Google codelab.
Here you can find that Firestore can be in Datastore mode which makes the previous tutorial suitable for you.
Related
I am having trouble figuring out if GCP Datastore supports querying nested properties of an entity.
My use case right now is like so:
Module
-> Application
Module
Application
#Entity
class Module {
Long id;
#Reference
Applicaiton application;
}
#Entity
class Application {
Long id;
String name;
}
I want to try query the module based on its nested Application name. I have tried providing the filter like so without success:
Query<? extends BaseEntity> query = Query.newEntityQueryBuilder()
.setKind("module")
.setFilter(PropertyFilter.eq("application.name", "UserApp"))
.build();
I'm using Springs GCP datastore abstraction through their DatastoreTemplate, but this doesn't seem related given that when I try run the GQL on the GCP console I get no results back either.
SELECT * FROM module WHERE application.name = "UserApp"
Thanks for taking the time to read through this. Any help with this is greatly appreciated!
It looks like you are using a Reference and not an embedded entity. The Application in module is really a key reference to an Application entity. Thus the values of application are not an indexed on the Module entity.
I have four tables in a database. When the user uses the Search option from the React application I want the search button to query all the tables and display data from all the tables which is AWS RDS MYSQL. How should I proceed? I am using Spring boot, mysql, and react.
I would recommend taking a look at JPA Respositories. Since your db seams to be small, a simple repository method like that one should make the trick.
However, if you have a more complicated requirement, you can use a Spring Projection. Create a query that retrieves all the fields you'll need, even if they're from different tables, and map the result into a Spring Projection
Using spring data jpa you should create a method in your repository that returns a list of your projection class:
public interface MyRepository extends Repository<MyEntityProjection, Long> {
#Query("SELECT ... WHERE field = ?1")
List<MyEntityProjection> getData(String param);
}
The projection class should be something like this:
public interface MyEntityProjection {
String getField();
String getField2();
}
Adding as many fields as your query returns.
Read the docs I linked for more information and examples.
My Spring Boot app is using Couchbase 5.1 community.
My app needs both a primary & several secondary indexes.
Currently, in order to create the needed indexes, I access the UI and the query page and manually create the indexes that the app needs as described here.
I was looking for a way to do it automatically via code, so when the app is starting, it will check if the indexes are missing and will create them if needed.
Is there a way to do it via Spring Data or via the Couchbase client?
You can create them by using the DSL from the index class. There's an example of using it in the documentation under "Indexing the Data: N1QL & GSI"
From that example:
You can also create secondary indexes on specific fields of the JSON,
for better performance:
Index.createIndex("index_name").on(bucket.name(), "field_to_index")
In this case, give a name to your index, specify the target bucket AND
the field(s) in the JSON to index.
If the index already exists, there will be an IndexAlreadyExistsException (see documentation), so you'll need to check for that.
So this is how I solve it:
import com.couchbase.client.java.Bucket;
public class MyCouchBaseRepository{
private Bucket bucket;
public MyCouchBaseRepository(<My Repository that extends CouchbasePagingAndSortingRepository> myRepository){
bucket = myRepository.getCouchbaseOperations().getCouchbaseBucket();
createIndices();
}
private void createIndices(){
bucket.bucketManager().createN1qlPrimaryIndex(true, false)
bucket.query(N1qlQuery.simple("CREATE INDEX xyz ON `myBucket`(userId) WHERE _class = 'com.example.User'"))
...
}
}
For example:
I want to store Employee detail such as
private Long id;
private String Name;
private String country;
Now, I also want to store an Image along with above data in MongoDB.
In my Controller, I have written below code its a snippet
Employee employee2 = new Employee();
employee2.setEmpId(1002);
employee2.setEmpName("Dinesh Rajput");
employee2.setCountry("India");
mongoOperations.save(employee2);
Employee data is created in DB. Now how to store image along with it.
Assuming you are using Spring Boot, Spring Data Mongo then you should consider using Spring Content for Mongo for the content storage piece like this:
Add the following dependencies to your pom.xml
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-mongo-boot-starter</artifactId>
<version>0.0.10</version>
</dependency>
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest-boot-starter</artifactId>
<version>0.0.10</version>
</dependency>
Make sure you have a GridFsTemplate bean present in your application context. Something like the following:
#Configuration
public class MongoConfig
#Bean
public GridFsTemplate gridFsTemplate() throws Exception {
return new GridFsTemplate(mongoDbFactory(), mappingMongoConverter());
}
...
To allow content to be associated with your Employee entity, give it the following attributes:
#ContentId
private String contentId;
#ContentLength
private long contentLength = 0L;
#MimeType
private String mimeType = "text/plain";
Add a store interface:
#StoreRestResource(path="employeeImages")
public interface EmployeeImageStore extends ContentStore<Employee, String> {
}
That's all that you need. When you application starts Spring Content will see the dependencies on the Mongo/REST modules and it will inject an implementation of the EmployeeImageStore store for GridFs as well as an implementation of a controller that supports full CRUD functionality and maps those operations down onto the underlying store interface. The REST endpoint will be available under /employeeImages.
i.e.
curl -X PUT /employeeImages/{employeeId} will create or update an employee's image
curl -X GET /employeeImages/{employeeId} will fetch the employee's image
curl -X DELETE /employeeImages/{employeeId} will delete the employee's image
There are a couple of getting started guides here. They use Spring Content for the filesystem but the modules are interchangeable. The Mongo reference guide is here. And there is a tutorial video here.
HTH
You can add the code like the following
DBObject metaData = new BasicDBObject();
metaData.put("mobileNo", mobileNo);
metaData.put("FileName", fileName);
metaData.put("createDate", new Date());
it will be saved in db like this
You have 2 options to achieve this.
Save image into local system and add property in your java object let's say imagePath.
Store it as binary data by using GridFS
Tutorial on how use GridFs
To upload data to the datastore I use this java code :
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
Entity entity = new Entity("mydetail");
entity.setProperty("entry", "entry");
ds.put(entity);
For uploading form based data is this the correct method of uploading data, ie using similar code above or is there another API I should be using ?
Yes, this the direct API to the AppEngine Datastore.
You can also use JDO interface which allows for directly storing a Java object without dealing with the Datastore API:
import javax.jdo.annotations.Persistent;
#PersistenceCapable
public class MyDetail {
// ...
#Persistent
private String entry;
// ...
There is also the JPA interface. Both of the interfaces are described on the App Engine website.
The Objectify interface is very easy and for many situations easier. It is not part of the official SDK.
You can use whichever makes more sense for you application.