Define primary key for several different objects in RavenDb - primary-key

Lets say that I have one object like:
class First
{
int key;
}
class Second
{
KeyValuePair<int,int> keyName;
}
Is it possible in RavenDb to define primary key using different name than "Id"? Please note that I need to assign different key name for different objects.

Gwynnbleid1,
Yes, you can. You can define this using the Conventiosn.FindIdentityProperty, which you can customize on a per type basis.

Related

Secondary Index on Custom Java Object in Aerospike

I have two classes.
class A {
String aName;
B b;
public A(String aName, B b) {
this.aName = aName;
this.b = b;
}
public String getaName() {
return aName;
}
public B getB() {
return b;
}
}
class B {
String bName;
public B(String bName) {
this.bName = bName;
}
public String getbName() {
return bName;
}
}
I am storing A as a set in Aerospike and A.aName is primary key. I want a secondary key on A.b. I have created index on A.b attribute and able to persist also. But search from the index is not returning anything. As per my understanding, Aerospike supports only three type of indexes: String, Numeric and Geo,. Is there any option for custom object.
Actually you can also index string, numeric and geo within different source types - basic (meaning just a bin with scalar data), list (so you can index strings or numeric data that is contained in a list), map keys and map values.
See: https://www.aerospike.com/docs/guide/query.html#secondary-index-key-source-type
You could model this in a few ways:
As a map. Let's assume that you store the value of A in a bin whose type is a map, it could have two map-keys - aName and bName. You can build a secondary index for string data on map values. Now, if you search for a specific bName you'll have this record come up.
More rationally you'd do the following as separate bins.
Assume that you use several bins, among them two bins to hold aname and bname. Their values are strings. You could now build a secondary index for string values and a basic index type (string data not contained in a complex data type such as list or map). You'd query for all the records where the predicate is bname = foo.
For a more complex situation one or more bname values map to a single aname, you'd actually model this as a lookup table.
Assume a set (table) called users holding records whose keys are the aname. A single key-value operation such as a read or an upsert works on a specific instance of class A, identified by a given aname. One record in Aerospike per instance of A.
You have another set (table) as the lookup table, where for each unique bname you create a record. The specific bname is the key to this record. The value is the aname. So to find the record in the users set, you first look it up in the lookup table by the bname. You use the value of this record as the key for the users record for that aname. This is the most common way of modeling this type of use case, without a secondary index.
Here is the answer post on Aerospike forum.
Binary blobs can be anything, there’s definitely no way to index that. If there is a particular field in your class you can pull out and set as a separate bin with a string/long type then that would work
https://discuss.aerospike.com/t/secondary-index-on-custom-java-object/6485

Map implementaion using arraylist as value

I am using Maps in my code for the first time, hence require some inputs from you experts.
My requirement is I have to check two different tables from database. Value from First table will be used as Key and Value for second table will be used as Value for the key.
Each key will have multiple values, so I will be storing all values against each key in a arraylist i.e. my Map will be like MAP.
Now, my issue is following:
I don't know the total no. of keys, so I can't create arraylist objects in advance. How to manage this?
How can I check if key exists in map such that if it exists then I have to updated the arraylist corresponding to it only. And if it doesn't exist then create new key, create arraylist corresponding to it, populate arraylist with the value.
Finally I have to iterate whole map and use the key and values.
How can it be implemented? Am I following the right approach? if not what is a better approach?
Thanks
With lists in Java you do not need to know the size up front. That is a requirement for Arrays. Therefore just create your Map
Map> myMap = new HashMap<>();
This should work
if (myMap.containsKey(someKey)) {
myMap.get(someKey).add(someValue); // adds a value to the list that already is in the map
} else {
myMap.put(someKey, Arrays.asList(someValue)); // which inserts a new key/value
}
If you need to iterate over all values in the list then you need a nested for loop
for (Map.Entry> entry : myMap.entrySet()) {
// your key = entry.getKey()
for (ValueType value : entry.getValue()) {
// use your value
}
}
http://docs.oracle.com/javase/7/docs/api/java/util/Map.html
Hope that helps.

Grails displaying values from two tables using primary and foreign keys

This is, I hope, probably quite obvious but I can't find an example that I think answers my issue.
I have an SQL database that I cant modify and within it are two tables, linked with primary/foreign keys (test_scenario and test_exec_queue respectively, so the PK value from test_scenario can show up many times within test_exec_queue) and when I display the data on screen I want it to, instead of displaying the FK value from test_exec_queue I want it to use that to get testScenarioName from the test_scenario table and display that instead.
So far my class looks like this but I've no idea what to put in to do the above logic, or do I do this somewhere else? In the controller? Any help appreciated
class TestExecQueue {
static constraints = {
testscenarioid(blank:false, editable:false)
myPriority(inList:[0,1,2,3,4], blank:false)
myState(inList:["READY"], blank:false)
}
static mapping = {
table "test_exec_queue"
version false
columns{
id column:"test_exec_queue_id"
testscenarioid column:"test_scenario_id"
myPriority column:"Priority"
myState column:"State"
}
}
Integer testscenarioid
Integer myPriority
String myState
}
You need to create a class which maps the test_scenario table in addition to the TestExecQueue class you've already implemented.
In your TestExecQueue class, you would link to the scenario by class, rather than by an integer field:
class TestExecQueue {
static mapping = {
scenario column:'test_scenario_id'
}
TestScenario scenario
}
Note: This is one example of mapping the relationship, you should review the Domain Modeling section of the Grails Documentation for other options.
The display of the classes is entirely dependent on your controllers and views, and that would need more elaboration on your part to answer clearly. One option is to set the public toString() methods on the classes that will be printed.

Castle ActiveRecord Error With View: NHibernate.PropertyNotFoundException for generated key

I'm mapping a view using ActiveRecord, which means I need a primary key. I don't have one, so I'm using ROW_NUMBER() to create one in the view definition to placate the system. However, I don't seem to know how to map it properly. I'm getting:
Could not find field 'stupidID' in class 'blah_blah'
NHibernate.PropertyNotFoundException: Could not find field 'stupidID' in class 'blah_blah'
My mapping looks like this. There is no
public long? stupidID;
[PrimaryKey("StupidId", Access = PropertyAccess.NosetterLowercaseUnderscore)]
public long? StupidId
{
get { return stupidID; }
}
Can anyone see what I'm missing?
NosetterLowercaseUnderscore means that by convention a prefix '_' is used and it's lowercase, so the field should be called _stupidid instead of stupidID.
Also, the PK shouldn't be a nullable type. I'd use long instead of long?

Is it possible to have a OneToOne relation to a class hierarchy persisted using JoinedBase?

I'd like one of my entities to have a one-to-one relationship with a class hierarchy. Think of it like a Strategy pattern, where each strategy needs different parameters to be persisted. I tried using a combination of OneToOne and JoinedBase/JoinedKey, but I've come across a problem.
With this combination, the primary key of the main entity also appears as the primary key of the table representing the root class in the hierarchy, and as the primary key of the subclass:
Order --------------- TaxCalculator
([PrimaryKey]Id = 1234) ([PrimaryKey(PrimaryKeyType.Foreign)]OrderId = 1234)
^
|
|
UkTaxCalculator
([JoinedKey]UkTaxCalculatorId = 1234)
I can persist this fine, but then I can't change which subclass of TaxCalculator I have. When I do something like:
order.TaxCalculator = new OverseasTaxCalculator(order);
then try to flush, then ActiveRecord/NHibernate (understandably) gets unhappy that there are now two TaxCalculators with Id = 1234.
I can get around this by replacing the OneToOne with a HasMany/BelongsTo, and hiding the multiplicity from users of the Order object, but I'm interested to know if it's possible to do this with OneToOne.
There's a full code example on github. This code throws an exception when the second SessionScope is disposed. If you clone the project, it should run out-of-the-box.
first of all i am sorry, but i did not tried my solution. It is to late and i really need my sleep ;-). I think the only way the one-to-one could work would be a 'table-per-hierarchy'-approach using a discriminator column instead of table-per-subclass. Maybe this will enable you to morph the existing object to another subclass. An other way, something like a polymorphic delete-orphan unfortunately is not supported as you stated. So i'll guess this would be your (very) last option.
But if this fails why don't you map it as a one-to-many instead of many-to-one with a foreign key in the order table, reusing the TaxCalculators? I would imagine them as quite static.
Interesting idea though: polymorphic delete-orphan.
We do something very similar to what you are trying to do. I think it's your combination of one-to-one and the joined key that's causing the problem. Try this:
[ActiveRecord, JoinedBase]
public class TaxCalculator
{
protected int TaxCalculatorId;
[PrimaryKey]
public virtual int Id
{
get { return TaxCalculatorId; }
set { TaxCalculatorId = value; }
}
// common tax calculation fields, methods etc...
}
[ActiveRecord]
public class OverseasTaxCalculator : TaxCalculator
{
[JoinedKey]
public override int Id
{
get { return TaxCalculatorId; }
set { TaxCalculatorId = value; }
}
// overseas tax calculation specific methods, properties etc...
}