You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+55-33Lines changed: 55 additions & 33 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,36 @@
1
1
# Aerospike Java Object Mapper
2
2
3
-
[Aerospike](https://www.aerospike.com) is one of, if not the fastest, NoSQL database in the world. It presents a Java API which is comprehensive and powerful, but requires a measure of boilder plate code to map the data from Java POJOs to the database. The aim of this repository is to lower the amount of code required when mapping POJOs to Aerospike and back as well as reducing some of the brittleness of the code.
4
-
3
+
[Aerospike](https://www.aerospike.com) is one of, if not the fastest, NoSQL database in the world. It presents a Java API which is comprehensive and powerful, but requires a measure of boiler plate code to map the data from Java POJOs to the database. The aim of this repository is to lower the amount of code required when mapping POJOs to Aerospike and back as well as reducing some of the brittleness of the code.
4
+
5
+
# Table of contents:
6
+
1.[Motivation and a simple example](#Motivation-and-a-simple-example)
7
+
2.[Getting Started](#Getting-Started)
8
+
3.[Constructors](#Constructors)
9
+
4.[Keys](#Keys)
10
+
5.[Fields](#Fields)
11
+
6.[Properties](#Properties)
12
+
7.[References to other objects](#References-to-other-objects)
13
+
+ 7.1. [Associating by Reference](#Associating-by-Reference)
14
+
+ 7.2. [Aggregating by Embedding](#Aggregating-by-Embedding)
15
+
+ 7.2.1. [Versioning Lists](#Versioning-Lists)
16
+
+ 7.2.2 [List Ordinals](#List-Ordinals)
17
+
+ 7.2.3 [The importance of Generic Types](#The-importance-of-Generic-Types)
@@ -248,14 +277,14 @@ However, there are times when this is not desirable, for example when the class
248
277
249
278
```java
250
279
@AerospikeRecord(namespace = "test", set = "testSet")
251
-
public class ConstructoredClass {
280
+
public class ConstructedClass {
252
281
@AerospikeKey
253
282
public final int id;
254
283
public final int age;
255
284
public final String name;
256
285
public final Date date;
257
286
258
-
public ConstructoredClass(int id, int age, String name, Date date) {
287
+
public ConstructedClass(int id, int age, String name, Date date) {
259
288
super();
260
289
this.id = id;
261
290
this.age = age;
@@ -265,18 +294,18 @@ public class ConstructoredClass {
265
294
}
266
295
```
267
296
268
-
As it stands, this class cannot be used with the AeroMapper because there is no valid constructor to invoke when an object needs to be created. There is a constructor but it does not contain enough information to map the reocrd on the database to the parameters of the constructor. (Remember that at runtime method and argument names are typically lost and become "arg1", "arg2" and so on). We can use this constructor, but we need to provide this missing information with annotations:
297
+
As it stands, this class cannot be used with the AeroMapper because there is no valid constructor to invoke when an object needs to be created. There is a constructor but it does not contain enough information to map the record on the database to the parameters of the constructor. (Remember that at runtime method and argument names are typically lost and become "arg1", "arg2" and so on). We can use this constructor, but we need to provide this missing information with annotations:
269
298
270
299
```java
271
300
@AerospikeRecord(namespace = "test", set = "testSet")
272
-
public class ConstructoredClass {
301
+
public class ConstructedClass {
273
302
@AerospikeKey
274
303
public final int id;
275
304
public final int age;
276
305
public final String name;
277
306
public final Date date;
278
307
279
-
public ConstructoredClass(@ParamFrom("id") int id, @ParamFrom("age") int age, @ParamFrom("name") String name, @ParamFrom("date")Date date) {
308
+
public ConstructedClass(@ParamFrom("id") int id, @ParamFrom("age") int age, @ParamFrom("name") String name, @ParamFrom("date")Date date) {
280
309
super();
281
310
this.id = id;
282
311
this.age = age;
@@ -305,14 +334,14 @@ Note that not all the fields in the class need to be specified in the constructo
305
334
306
335
```java
307
336
@AerospikeRecord(namespace = "test", set = "testSet")
308
-
public class ConstructoredClass2 {
337
+
public class ConstructedClass2 {
309
338
@AerospikeKey
310
339
public final int id;
311
340
public final int a;
312
341
public int b;
313
342
public int c;
314
343
315
-
public ConstructoredClass2(@ParamFrom("id") int id, @ParamFrom("a") int a) {
344
+
public ConstructedClass2(@ParamFrom("id") int id, @ParamFrom("a") int a) {
316
345
this.id = id;
317
346
this.a = a;
318
347
}
@@ -325,19 +354,19 @@ If there are multiple constructors on the class, the one to be used by the AeroM
325
354
326
355
```java
327
356
@AerospikeRecord(namespace = "test", set = "testSet")
328
-
public class ConstructoredClass2 {
357
+
public class ConstructedClass2 {
329
358
@AerospikeKey
330
359
public final int id;
331
360
public final int a;
332
361
public int b;
333
362
public int c;
334
363
335
-
public ConstructoredClass2(@ParamFrom("id") int id, @ParamFrom("a") int a) {
364
+
public ConstructedClass2(@ParamFrom("id") int id, @ParamFrom("a") int a) {
336
365
this.id = id;
337
366
this.a = a;
338
367
}
339
368
@AerospikeConstructor
340
-
public ConstructoredClass2(@ParamFrom("id") int id, @ParamFrom("a") int a, @ParamFrom("b") int b) {
369
+
public ConstructedClass2(@ParamFrom("id") int id, @ParamFrom("a") int a, @ParamFrom("b") int b) {
341
370
this.id = id;
342
371
this.a = a;
343
372
this.b = b;
@@ -810,7 +839,7 @@ loadedPerson : Person
810
839
811
840
Note that if a reference to an AerospikeRecord annotated object exists, but the reference has neither @AerospikeReference nor @AerospikeEmbed (see below), then it is assumed it will be @AerospikeReference(lazy = false).
812
841
813
-
There are times when it makes sense to store the digest of the child record as the reference rather than it's primary key. For example, if the native primary key is of significant length then storing a fixed 20-byte digest makes sense. This can be accomplished by adding `type =ReferenceType.DIGEST` to the @AeropikeReference. For example:
842
+
There are times when it makes sense to store the digest of the child record as the reference rather than it's primary key. For example, if the native primary key is of significant length then storing a fixed 20-byte digest makes sense. This can be accomplished by adding `type =ReferenceType.DIGEST` to the @AerospikeReference. For example:
Here the transaction time is the second attribute in each list, and the amount is the first attribute. However, a common request is to be able to extract transaction by time. For example, in fraud detection systems, there may be a need to load the N most recent transactions. If the transactions were to be stored with the transaction time as the first element in the list, efficient CDT perations in Aerospike such as `getByValueRange(...)` can be used.
1194
+
Here the transaction time is the second attribute in each list, and the amount is the first attribute. However, a common request is to be able to extract transaction by time. For example, in fraud detection systems, there may be a need to load the N most recent transactions. If the transactions were to be stored with the transaction time as the first element in the list, efficient CDT operations in Aerospike such as `getByValueRange(...)` can be used.
1166
1195
1167
1196
This ordering can be controlled by the @AerospikeOrdinal annotation:
1168
1197
@@ -1302,7 +1331,7 @@ An example using an environment variable:
1302
1331
privateString title;
1303
1332
```
1304
1333
1305
-
In this case, if the environment variable ``ACCOUNT_TITLE_BIN_NAME`` is set, that will be the name of the bin which is used. If it is not set, it will be like the annotation does not specify the ``name`` paramteter at all, which means that the field name (``title``) will be used for the bin name.
1334
+
In this case, if the environment variable ``ACCOUNT_TITLE_BIN_NAME`` is set, that will be the name of the bin which is used. If it is not set, it will be like the annotation does not specify the ``name`` parameter at all, which means that the field name (``title``) will be used for the bin name.
1306
1335
1307
1336
----
1308
1337
@@ -1597,7 +1626,7 @@ Sometimes, the representation of the data in Aerospike and the representation in
1597
1626
1598
1627
```java
1599
1628
public enum Suit {
1600
-
CLUBS, DIAMONDS, HEARTS, SPADES;
1629
+
CLUBS, DIAMONDS, HEARTS, SPADES
1601
1630
}
1602
1631
1603
1632
@AerospikeRecord(namespace=NAMESPACE, set="card")
@@ -1841,14 +1870,15 @@ Top level is an array of classes. Each class has:
1841
1870
- **key**: a [key structure](key-structure), specified below
1842
1871
- **bins**: a list of [bin structure](bin-structure), specified below
1843
1872
- **version**: The version of the record. Must be an integer with a positive value. If not specified, will default to 1. See [Versioning Links](#versioning-lists) for more details.
1844
-
1873
+
1845
1874
#### Key Structure
1846
-
The key structure contains:
1847
-
- **field**: the field for the key. Can be unspecified if methods are being used for the key
1848
-
- **getter**: the name of the method to be used as the getter for the key.
1849
-
- **setter**: the name of the method to be used as the setter for the key. This is optional -- if lazy loading of referenced objects is used, a setter must be specified for the child classif a getter is
1850
-
Note that either a field should be specified, or a getter (potentially with a setter). Using both a field and a getter will throw an error. Also note that the method is specified by names only, not parameters so it is a good idea to us a unique method.
1851
-
1875
+
The key structure is used to specify the key to a record. Keys are optional in some situations. For example, if Object A embeds an Object B, B does not need a key as it is not stored in Aerospike in its own right.
1876
+
1877
+
The key structure contains:
1878
+
- **field**: The name of the field which to which this key is mapped. If this is provided, the getter and setter cannot be provided.
1879
+
- **getter**: The getter method used to populate the key. This must be used in conjunction with a setter method, and excludes the use of the field attribute.
1880
+
- **setter**: The setter method used to map data back to the Java key. This is used in conjunction with the getter method and precludes the use of the field attribute. Note that the return type of the getter must match the type of the first parameter of the setter, and the setter can have either 1 or 2 parameters, with the second (optional) parameter being either of type [com.aerospike.client.Key](https://www.aerospike.com/apidocs/java/com/aerospike/client/Key.html) or Object.
1881
+
1852
1882
#### Bin Structure
1853
1883
The bin structure contains:
1854
1884
- **embed**: An [embed structure](#embed-structure) used for specifying that the contents of this bin should be included in the parent record, rather than being a reference to a child record. There can only be one embed structure per field, and if an embed structure is present, a [reference structure](#reference-structure) cannot be. If a field refers to another AerospikeRecord, either in a collection or in it's own right, and neither an embed or reference structure is specified, a reference will be assumed by default.
@@ -1859,14 +1889,6 @@ The bin structure contains:
1859
1889
- **ordinal**: For items mapped as lists, this ordinal specifies the location of this bin in the list. If this is not provided, the position of the bins in the list will be determined by alphabetical ordering.
1860
1890
- **reference**: A [reference structure](#reference-structure) detailing that a child object referenced by this bin should be stored as the key of the child rather than embedding it in the parent object. The use of a reference precludes the use of the embed attribute, and if neither is specified then reference is assumed as the default.
1861
1891
- **setter**: The setter method used to map data back to the Java POJO. This is used in conjunction with the getter method and precludes the use of the field attribute. Note that the return type of the getter must match the type of the first parameter of the setter, and the setter can have either 1 or 2 parameters, with the second (optional) parameter being either of type [com.aerospike.client.Key](https://www.aerospike.com/apidocs/java/com/aerospike/client/Key.html) or Object.
1862
-
1863
-
#### Key Structure
1864
-
The key structure is used to specify the key to a record. Keys are optional in some situations. For example, if Object A embeds an Object B, B does not need a key as it is not stored in Aerospike in its own right.
1865
-
1866
-
The key structure contains:
1867
-
- **field**: The name of the field which to which this key is mapped. If this is provided, the getter and setter cannot be provided.
1868
-
- **getter**: The getter method used to populate the key. This must be used in conjunction with a setter method, and excludes the use of the field attribute.
1869
-
- **setter**: The setter method used to map data back to the Java key. This is used in conjunction with the getter method and precludes the use of the field attribute. Note that the return type of the getter must match the type of the first parameter of the setter, and the setter can have either 1 or 2 parameters, with the second (optional) parameter being either of type [com.aerospike.client.Key](https://www.aerospike.com/apidocs/java/com/aerospike/client/Key.html) or Object.
1870
1892
1871
1893
#### Embed Structure
1872
1894
The embed structure is used when a child object should be fully contained in the parent object without needing to be stored in the database as a separate record. For example, it might be that Customer object contains an Address, but the Address is not stored in a separate table in Aerospike, but rather put into the database as part of the customer record.
@@ -1941,7 +1963,7 @@ public class Container {
1941
1963
}
1942
1964
````
1943
1965
1944
-
Note that in thiscase the items are embedded into the container and not refrenced. This is what is needed for virtual lists, they must have a list of items in the database associated with a single record.
1966
+
Note that in thiscase the items are embedded into the container and not referenced. This is what is needed for virtual lists, they must have a list of items in the database associated with a single record.
1945
1967
1946
1968
These items can be populated using the functionally presented above. For example:
1947
1969
@@ -2001,7 +2023,7 @@ name: "container"
2001
2023
```
2002
2024
2003
2025
Note however that the list in the object in memory still contains only 4 items. *Virtual lists affect only the database representation of the data and not the Java POJO.*
2004
-
eVirutal Lists tend to use the (Operate)[https://www.aerospike.com/docs/client/java/usage/kvs/multiops.html] command which allows multiple operations to be performed on the same key at the same time. As a consequence, multiple commands can be done on a list with a single Aerospike operation. For example:
2026
+
Virtual Lists tend to use the (Operate)[https://www.aerospike.com/docs/client/java/usage/kvs/multiops.html] command which allows multiple operations to be performed on the same key at the same time. As a consequence, multiple commands can be done on a list with a single Aerospike operation. For example:
0 commit comments