I have two comboboxes connected to a two DatabaseTables in ORMLite. For exammple first combobox shows brands (from brands_table) and second shows models (from models_table). Models_table has also foreignField with brandId. When I'm saving a new record, I must choose brand first then model.
For initializaton and set data in both of comboboxes I use queryForAll method from DAO.
My question is which method I could use for filtering data in second combobox when I already choose something from first. I was thinking about queryForEq and queryForMatching.
For now normal initialize is:
public void initializeModelsList() throws ApplicationException {
CarModelDao carModelDao = new CarModelDao(DBManager.getConnectionSource());
List<CarModel> listOfModels = carModelDao.queryForAll(CarModel.class);
modelsList.clear();
// loop
listOfModels.forEach((c) -> {
// create new object ModelsFX model
ModelsFX modelsFX = ConverterModels.convertToModelFX(c);
this.modelsList.add(modelsFX);
And what I'm thinking about is:
public void initializeFilteredModelsList() throws ApplicationException {
CarBrandDao carBrandDao=new CarBrandDao(DBManager.getConnectionSource());
CarBrand tempCarBrand = carBrandDao.findById(CarBrand.class, this.getModelsFxObjectProperty().getBrandsFXObjectProperty().getId());
//it returns int with ID
CarModelDao carModelDao = new CarModelDao(DBManager.getConnectionSource());
List<CarModel> listOfFilteredModels = carModelDao.//searching for same ID in foreignField(brand_ID) in models_table
listOfFilteredModels.forEach((c) -> {
// create new object ModelsFX model
ModelsFX modelsFX = ConverterModels.convertToModelFX(c);
this.modelsList.add(modelsFX);
});
My question is which method I could use for filtering data in second combobox when I already choose something from first.
If I understand, this is textbook example of foreign objects that is covered very well by the documentation for ORMLite. In the examples from the docs they have Account and Order which in your example would be CarBrand and CarModel.
To quote from the docs:
You can query for foreign fields in a couple of different ways. The following examples show code which queries for all orders that match a certain account field. Since the id field is the name field, you can query by the name field of the account:
// query for all orders that match a certain account
List<Order> results = orderDao.queryBuilder().
where().eq("account_id", account.getName()).query();
Or you can just let ORMLite extract the id field from the account itself. This will perform an equivalent query to the above:
// ORMLite will extract and use the id field internally
List<Order> results = orderDao.queryBuilder().where().eq("account_id", account).query();
Related
Say I have the following POJO with the necessary methods and stuff to successfully load and save items into a DDB table:
#DynamoDBTable(tableName = "my_ddb_table")
public class MyDDBTableItem {
#DynamoDBHashKey(attributeName="id")
private String id; // primary key
private String a_value;
private Set<String> some_values;
}
I am using dynamoDBMapper.batchload(), so I need to take action if the exception is thrown. I have never worked with DDB before, so I am unsure of what some of their terms mean (e.g. for getKeys(): "The primary key attribute values that define the items and the attributes associated with the items.").
What I currently want to do is just get some collection (list, set, etc.) of the unprocessed primary keys. Is this the right way to do it (I don't know how I'd test it)?
try {
dynamoDBMapper.batchload(itemsToGet)...
} catch (BatchGetItemException e) {
// I could get them as strings or as the instances of the class MyDDBTableItem, but I'll use String here.
List<String> unprocessedKeys = e.getUnprocessedKeys()
.get("my_ddb_table")
.getKeys() // after this is where I am unclear.
.stream()
.map(map -> map.get("id").getS())
.collect(Collectors.toList());
...
}
Since you are using the higher level DynamoDB mapper, you don't actually need to catch that exception. You can specify how unprocessed keys are handled by using a strategy class implementing DynamoDBMapperConfig.BatchLoadRetryStrategy.
By default, the DynamoDB client will use the DefaultBatchLoadRetryStrategy.
// TODO: implement the strategy interface
BatchLoadRetryStrategy myCustomStrategy = ...;
dynamoDBMapper.batchLoad(itemsToGet, new DynamoDBMapperConfig.Builder().
withBatchLoadRetryStrategy(myCustomStrategy))
The KeysAndAttributes class is used to construct a list of items (by specifying their primary keys) and attributes (which columns to fetch) from a DynamoDB table. You can construct an instance of that class like this:
KeysAndAttributes kna = new KeysAndAttributes().withKeys(keysToLoad);
Basically, you would only want to call getUnprocessedKeys() manually if you are working with the lower level API for loading items in batches.
I'm implementing the PUT Methods for a REST-API.
I have a POJO similar to the following:
public class Brand implements Serializable {
#Column(columnDefinition = "serial")
#Generated(GenerationTime.INSERT)
#JsonIgnore
private Integer id;
#Id
#JsonProperty("brand")
private String brand;
.
.
.
}
Within the postgresql database the brand table has the following columns:
a database-internal id (SERIAL) which shall not be visible to the outside.(This is used manly for joining tables)
a brand (TEXT) which is the primary key
My Service method looks like this:
public Brand updateBrand(String brand, Brand update) {
Brand b = brandRepository.findBrandByBrand(brand);
if(b == null) { //If not exists create new one
b = new Brand(null, brand);
}
else { //If exists keep id, delete old one and create new entry
if(update != null && update.getBrand() != null) {
brandRepository.delete(b);
}
ServiceUtils.copyProperties(update, b); //This is within the if clause, because brand is the only value
}
return brandRepository.save(b);
}
And the controller would have something like this:
#PutMapping(value = "/brand/{brand}")
public ResponseEntity<Brand> updateBrand(#PathVariable("brand") String brand,
#RequestBody Brand update) {
Brand updated = articleNumberService.updateBrand(brand, update);
if(updated == null) {
throw new EntryCreationFailedException(brand); //self made exception
}
return new ResponseEntity<>(updated, HttpStatus.OK);
}
Now my following problem is, that when calling PUT ../brand/stackoverflow
with body:
{"brand":"StackOverflow")
it deletes the old stackoverflow brand (which had id=1, for example) and creates a new one called StackOverflow. But when checking the database the id column is incremented (so now it has id=2).
I checked and this is caused by hibernate still calling:
insert
into
brand
(brand)
values
(?)
This definitly is what I want when id is null. Which happens when creating a new Brand for example. But when only overriding the brand and id is not null I want hibernate to call this:
insert
into
brand
(id, brand)
values
(?, ?)
I know this would be possible by creating a own save method and in an emergency override the query. BUT I'm quite optimistic that this should be possible without. Bt I can't realy find fitting answers to this. I already had problems finding the proper annotations for the postgresql-specific serial behavior.
P.S: I know that some will shout "why would you have Brand as the primary key and not id!?" But this only is a simple class/part of the database. There are more complex classes which use exactly the same way for the internal database id, (and actually need it), but have multiple primary keys etc. So this rather is a very simple representation for my problem.
Since the Postgres use the serial as the auto_increment, it's not included the id insertion in sql statement. Behind the scene, it create the sequence for it. So you should use the Generation type IDENTITY for it.
If it was a field with #Id you would be able to write a custom #GenericGenerator that fetched the sequence if the value was null, but as it's not a primary key, I think you would end up having to have a separate parent Entity with its own generated Id.
I'm trying to delete an object from datastore but it's not deleting it. Code is given below:
MoIADocument moIADoc = new MoIADocument();
// update fields in moIADoc object
ds.save(moIADoc);
printDBDocs();
// create a query to retrieve objects
QueryResults<MoIADocument> foundResults = dao.find(query);
List<MoIADocument> list = foundResults.asList();
for (MoIADocument obj : list) {
ds.delete(obj);
MoDBIATopic topicBO = obj.getData().get(EnumChannelType.FACEBOOK).getData().get(GraphConstants.Topic_Default);
topicBO.setInfluence(topicBO.getInfluence() * 25);
ds.save(obj);
}
printDBDocs();
###########################
the result of first print (in JSON format) is:
###########################
obj in for loop is:
###########################
and after for loop the print statement gives two objects as:
Why is it not deleting old object by mongoConstants.ds.delete(obj);? And I have annotated id field ad #Id but still two objects are saved with same id. How is this possible? How can we force to overwrite an object if id is same?
#Id
#Indexed
private String id;
Note: id is the top level id as indicated in JSON.
And I tried using query as:
Query<MoIADocument> query1 = ds.createQuery(MoIADocument.class).disableValidation();
query1.field("id").equal(obj.getId());
ds.delete(query1);
This too not working as expected.
EDIT:
Problem looks like in query result. Using above query1, it returned zero results.
I tried multiple approaches but nothing worked as expected.. tried following ways:
Approach# 1:
Query<MoDBIADocument> query1 = dao.createQuery(MoDBIADocument.class).disableValidation();
query1.field("id").equal(moDoc.getId());
QueryResults<MoDBIADocument> foundResults1 = dao.find(query1);
printDBDocs(foundResults1);
Approach# 2: (using _id instead of id)
Query<MoDBIADocument> query1 = dao.createQuery(MoDBIADocument.class).disableValidation();
query1.field("_id").equal(moDoc.getId());
QueryResults<MoDBIADocument> foundResults1 = dao.find(query1);
printDBDocs(foundResults1);
Approach# 3:
using `ds` instead of `dao` in `Approach# 1` and `Approach# 2`
Approach# 4:
DBObject dbObj = new BasicDBObject("id", moDoc.getId());
DBCursor cursor = COLLECTION.find(dbObj);
None of above approaches worked.. I think problem is with using top level id field (somehow?)..
Using internal id (of FACEBOOK) worked as expected
query1.field("data.FACEBOOK.id").equal(str);
Problem was using a String id as #Id field. Actually it should be ObjectId id. WIth this change class become as below:
#Entity("Collection_IAGlobals")
public class MoDBIADocument {
#Id
#Indexed
private ObjectId id;
// some more fields
}
and updating as:
QueryResults<MoIADocument> foundResults = dao.find(query);
List<MoIADocument> list = foundResults.asList();
for (MoIADocument obj : list) {
//do modifications in obj
dao.save(obj);
}
this way there is no need to delete old object. It replaces old object with new one (since they are having same id).
Works fine using both ds and dao.
But now, new problem with setting id field. If I set using some string as:
moIADoc.setId(new ObjectId("123456"));
it is resulting into following error:
Exception in thread "main" java.lang.IllegalArgumentException: invalid ObjectId [123456]
at org.bson.types.ObjectId.<init>(ObjectId.java:128)
at org.bson.types.ObjectId.<init>(ObjectId.java:122)
It works fine any of other methods, like:
// don't set id field
//OR
//set using default constructor of ObjectId
moIADoc.setId(new ObjectId());
//OR use other constructors e.g.
moIADoc.setId(new ObjectId(new Date(), 123456));
So, the question is why ObjectId is not taking String argument?
I am using objectify-appengine framework for querying. Here is my simplified problem: Consider these 2 classes:-
public class Customer {
#Id private String email;
#Embedded private Account Account = new Account(); // note embedded annotation
}
and
public class Account {
private String number; //example: 1234
}
The following query works & gives me 1 customer:
Objectify ofy = ObjectifyService.begin();
ofy.query(Customer.class).filter("account.number = ", "1234");
Question:
However, if have a List of values (account numbers). Is there a way to fetch them in 1 query? I tried passing a list of account numbers like this:
ofy.query(Customer.class).filter("account.number = ", myAccountNumberList);
But if fails saying:
java.lang.IllegalArgumentException: A collection of values is not allowed.
Thoughts?
filter("account.number IN", theList)
Note that IN just causes the GAE SDK to issue multiple queries for you, merging the results:
The IN operator also performs multiple queries, one for each item in the specified list, with all other filters the same and the IN filter replaced with an EQUAL filter. The results are merged, in the order of the items in the list. If a query has more than one IN filter, it is performed as multiple queries, one for each possible combination of values in the IN lists.
From https://developers.google.com/appengine/docs/java/datastore/queries
I have a GWT 2.4 project using a CellTable.
It has columns like this (actually more):
LastName --- FirstName --- Departments
Smith Tom Research, Management
The names I get from a "User" object which is created on the server from my Database.
The DB looks like this:
users:
userID
firstName
lastName
departments:
departmentID
departmentName
user_in_department:
userID
departmentID
So what is the best way to get my departments show up in the table?
At the moment I fetch the User-list and the Department-list from the server using a RPC.
I thought about a 3rd RPC to get me the user-department relation and then match the names to the users on the client. What would be a good way to match that btw?
But even if I had the departments matched to my users, how would I add that info to the table?
For the names I can just do that:
TextColumn<User> firstNameColumn = new TextColumn<User>() {
#Override
public String getValue(User object) {
return object.getFirstName();
}
};
But as the departments aren't stored in the "User" object, I have no idea how to get them in the correct column and row.
I hope I've explained my issue good enough for you to understand :)
Assuming that your User object has a list of departments like so:
public ArrayList<Department> getDepartments() {
// ...
}
You can create a column to list the departments like so:
TextColumn<User> departmentsColumn = new TextColumn<User>() {
#Override
public String getValue(User object) {
StringBuilder departments = new StringBuilder();
for(int i=0; i < object.getDepartments().size(); i++) {
if (i>0) {
departments.append(",");
}
departments.append(object.getDepartments().get(i).getDepartmentName());
}
return departments.toString();
}
};
In addition to the first answer: since a CellTable is parameterized to display a list of objects of a given type in its rows that object should include the user name as well as a list of departments. You'll have to somehow make that data available through the User object, or create a new one (e.g. UserDepartmentDTO) as the elements in the underlying model.