How to flush data to Spring data elastic search - spring-data

I run this testcase
Envelope envelope = new Envelope();
envelope.setId("1");
Envelope saved = envelopeRepository.save(envelope);
assertThat(saved.getId()).isEqualTo("1");
saved and envelope are the same object/reference! So even when the index is incorrect, the test still passes! How to fix this issue?
org.elasticsearch.client.RestClient - request [HEAD http://localhost:9200/null?ignore_throttled=false&ignore_unavailable=false&expand_wildcards=open%2Cclosed&allow_no_indices=false]

Why should the saved entity be a new object? Elasticsearch does not return a document when saving, so there is no need to create a new object here.
What Spring Data Elasticsearch does is update this object with the information returned from the index operation:
the id if it was not already set on the object but was created by Elasticsearch
version if the entity has a version property
seq_no and primary_term if the entity has such a property
If the indexing fails, an exception is thrown.
What do you mean with
when the index is incorrect
And what has the HEAD request do do with this?

Related

.net core handle PostreSQL db exceptions

I have a .net core web api. Db is PostreSQL. I have a simple POST request that create an entity with two fields:
public class ClientDto{
public string Name {get;set;}
public int ClientId{get;set;}
}
ClientId - FK foreign key to table Clients.
Some client (Postman for exapmle) execute request, but in data model send ClientId that not exists in db.
I have global exeption handler and there I handle db exception, but exception object don't include separated information.
I would like to show to user beautiful message something like "Client with id = 1 not exists".
What the best practis to handle db exceptions?
May be before save object in db I need check if client with id = 1 exists in db? But it is an additional query.
May be before save object in db I need check if client with id = 1 exists in db? But it is an additional query.
I'd do this.
If your client doesn't give you good information in its exception then your probably better to do the additional query. If you're querying on an indexed field (which i'd expect given you are using a foreign key) then it will be a very quick query.
Exception throwing and catching is fairly expensive anyway and i'd probably be happy enough with the extra call.

Retrieving some columns from database with Breeze.js, and still be able to update database

I am new to Breeze.js, but really enjoy it so far. I ran into an issue with updating a database with Breeze.js, when selecting only portion of columns of a model.
When I ran this statement:
$scope.emFac.entityQuery.from('Company');
the company entity matches my EF entity, retrieves all columns, creates entityAspect, and all is working fine when updating database:
However, when I retrieve only portion of corresponding Model's columns, Breeze.js returns anonymous object with specified properties (retrieving data works, but not updating does not), without the entityAspect, which is being used for tracking changes.
Here is the code with select statement:
$scope.emFac.entityQuery.from('Company').select('companyId, displayName');
Is there a way to retrieve only some columns of EF Model columns, and still track changes with Breeze.js, needed for database updates?
As you've discovered, Breeze treats the incoming data as plain objects instead of entities when you use select.
Your choices are:
On the server, Create a CustomerLite or similar object, and have a server endpoint that returns those without the need for select; OR
On the client, get the results from the query and create entities from each object, with status Unchanged
Example of #2:
var entities = [];
em.executeQuery(customerProjectionQuery).then(queryResult => {
queryResult.results.forEach(obj => {
// obj contains values to initialize entity
var entity = em.createEntity(Customer.prototype.entityType, obj, EntityState.Unchanged);
entities.push(entity);
});
})
Either way, you will need to ensure that your saveChanges endpoint on the server can handle saving the truncated Customer objects without wiping out the other fields.

Get entity JPA Id after merge?

I have a freshly created entity (detached because not yet saved in the DB). This entity holds another entity that already exists in the db (but is detached, too). Thus, I would use em.merge(myNewEntity) to store it.
If I want to get the new created ID, I would use em.flush() afterwards. Then I invoke myNewEntity.getId(). With persist I receive an ID generted by the DB/JPA. With merge, it does not. The ID in the object remains null. Why is that?
The result of the merge operation is not the same as with the persist operation - the entity passed to merge does not become managed. Rather, a managed copy of the entity is created and returned. This is why the original new entity will not get an id. So instead of
em.merge(newEntity);
Long id = newEntity.getId();
it should be
managedEntity = em.merge(newEntity);
Long id = managedEntity.getId();

How to get Hibernate Search to index

I have an app that I'm attempting to integrate hibernate search into. I'm using Hibernate Search 3.4.2. I have a domain class that looks like the following:
#Indexed
public Group {
#Fieldindex (index = Index.TOKENIZED, store = Store.YES)
private String groupName;
}
In my test cases, I create a few Groups and save them to the database. Once stored in the database, I create the index and then search for given text strings. This seems to work.
The problem I'm having is that any new Groups created after the index has been created are not indexed. From what I've read, I thought that once the index is created, any new items persisted would be automatically indexed with the new values, but this doesn't seem to be the behavior I'm getting. Is there something I've missed in the way of configuration? Or do I have to do something manually to tell Hibernate Search that I've added a new object to be indexed?
Needless to say, I'm a bit confused...
[EDIT] I'm using JPA, so my hibernate search confguration is contained in my persistence.xml as follows:
<property name="hibernate.search.default.directory_provider" value="filesystem"/>
<property name="hibernate.search.default.indexBase" value="D:\var2\lucene\indexes"/>
I can see that the index files are created, and I can use Luke to view the contents, they just don't ever seem to get updated when I persist a new object.
As stated in the documentation "By default, every time an object is inserted, updated or deleted through Hibernate, Hibernate Search updates the according Lucene index".
What I would do is to check my persistence.xml and see if I have not accidentally set hibernate.search.indexing_strategy = manual
If that's not the case, maybe you could try to force it and see if that works?
hibernate.search.indexing_strategy = event
Which framework are you using? Maybe check out the last post of this question.
// Jakob

Core Data primary key ID for a row in the database

Suppose I have a list of books stored in Core Data. I want to search for a book by it's primary key ID.
I know the sqlite file created by Core Data has an ID column in each table, but this doesn't seem to be exposed to me in anyway.
Does anyone have any recommendations?
-[NSManagedObject objectID] is the unique ID for an object instance in Core Data. It can be serialized via -[NSManagedObjectID URIRepresentation]. You can retrieve the objectID from a persistent store coordinator with -[NSPersistentStoreCoordinator managedObjectIDForURIRepresentation:] and then get the object from a managed object context with -[NSManagedObjectContext objectWithID:].
BUT
You should keep in mind that Core Data is not an ORM. It is an object graph management framework. That is uses SQLite (and unique row IDs) as a backend is purely an implementation detail. The sooner you can get yourself out of the SQL/RDBMS mindset, the faster you will be happy with Core Data. Instead of trying to find an object from a stored ID, consider why you need that object and what object needs it. If an instance of class Foo needs to be able to get to an instance of class Bar, why not just create an association from the Foo to the Bar and set the appropriate Bar instance as the target of the association on the appropriate Foo instance. Let Core Data keep track of object IDs.
As Barry Wark said, remember always that Core Data is not an orm. Pure SQL details are not exposed to the user and every row is just an object. By the way, sometime you should need to access the "primary key", for example when you need to sync the coredata db with external sql databases (in my case I needed it in a callback function to change the state of an object after INSERT it with success in the remote db). In this case, you can use:
objectId = [[[myCoredataObject objectID] URIRepresentation] absoluteString]
that will return a string like: x-coredata://76BA122F-0BF5-4D9D-AE3F-BD321271B004/Object/p521 that is the unique id used by Core Data to identify that object.
If you want to get back an object with that unique id:
NSManagedObject *managedObject = [managedObjectContext objectWithID:[persistentStoreCoordinator managedObjectIDForURIRepresentation:[NSURL URLWithString:objectId]]];
NB: Remember that if the receiver has not yet been saved in the CoreData Context, the object ID is a temporary value that will change when the object is saved.
This is the way you can get the object id as String using Swift from a NSManagedObject:
entity.objectID.uriRepresentation().absoluteString
in Swift this will be done by getting ID of the row as URI then get last path of URI
entity.objectID.uriRepresentation().lastPathComponent
the output of last path will look like this
p12
this output is string so you can remove the p using:
trimmingCharacters()
// Like this
let id = entity.objectID.uriRepresentation().lastPathComponent.trimmingCharacters(in: ["p"])