xetorthio / johm Goto Github PK
View Code? Open in Web Editor NEWJOhm is a Object-hash mapping library for Java for storing objects in Redis
License: MIT License
JOhm is a Object-hash mapping library for Java for storing objects in Redis
License: MIT License
Using reflection to parse models and to check it at runtime is a clear bottleneck since this model (Class<?>, Field ....) doesn't change at runtime.
Moreover looping over all field to get the id (one example) is a bad design too.
Adding a method JOhm.register(Class<?>) to do all this stuff and simply set values @ runtime can be a great enhancement for next versions from a performance point of view.
Note: that's the reason why in all Java ORM like JPA for instance the entitymanagerfactory is created only once by application.
Is it possible for jOhm to include commands on database such as "select", "flushdb"?
Thanks,
Peter
Part of the the List, Set, and Map interfaces is implementing hashcode and equals. RedisList, RedisMap, RedisSet, and RedisSortedSet do not implement hashcode nor equals.
Right now JOhm has only static methods, which does not allow multiple instances of it to be created.
I maybe have a different JedisPool pointing to the master and a separate one pointing to a cluster of slaves for read-only operations.
There is no way to use JOhm when you have two separate JedisPool instances.
redis\clients\johm\JOhm.java
// always add to the all set, to support getAll
nest.cat("all").sadd(String.valueOf(JOhmUtils.getId(model)));
it cause :
"SADD" "User:all" "2"
"SADD" "User:all" "2"
"SADD" "User:all" "2"
"SADD" "User:all" "2"
...
in which situation,it is used,who can show one ?
i can not understand the comments "always add to the all set, to support getAll"
Hi,
I'm having problems using JOhm since the connection pool gets exhausted. It seems that connections are not being returned to the pool for some reason. After a bunch of requests I start receiving errors saying: Could not get resource from the pool.
I've tried every workaround I've found but without any luck. I started thinking that it is a JOhm issue because it doesn't return connections if an exception occurs.
Regards
It would be great to be able to use a string or UUID as the key.
Getting such error redis.clients.johm.JOhmException: java.lang.IllegalArgumentException: Can not set java.lang.Long field User.id to java.lang.Integer
. Did everything as it was described in example. Might that be a bug in 0.5.0 version?
public class Test
{
public static void main( String[] args )
{
// Jedis use
JedisPool jedisPool = new JedisPool( new Config(), "localhost" );
JOhm.setPool( jedisPool );
User user1 = new User();
user1.setName( "Jhon" );
user1.setAge( 30 );
JOhm.save( user1 );
}
}
@Model
class User {
@Id
private Long id;
@Attribute
private String name;
@Attribute
private int age;
public Long getId()
{
return this.id;
}
public void setName( String Name )
{
this.name = Name;
}
public String getName()
{
return this.name;
}
public void setAge( Integer Age )
{
this.age = Age;
}
public Integer getAge()
{
return this.age;
}
}
Currently, this line in internalPut() at redis.clients.johm.collections.RedisMap
hash.put(key.toString(), JOhmUtils.getId(value).toString());
forces to fetch the id of the current value in a Map collection, which fails after trying to check whether it's a valid Model or not, by throwing a JOhmException ("Class pretending to be a Model but is not really annotated").
This behavior prevents the insertion of non-Model values in a Map, such as any "boxed primitive" type.
The following assertions are not true:
assertEquals(user1.getId(), users.get(0).getId());
assertEquals(user3.getId(), users.get(1).getId());
We need to patch JOhm to ignore all annotations but @id on the designated id field in every model. Also need to update the documentation to reflect this. I am thinking if we could create some kind of an FAQ on the wiki, that would also be helpful for users.
When attempting to use ShardedJedisPool, the IDE reports "The method setPool(JedisPool) in the type JOhm is not applicable for the arguments(ShardedJedisPool).". Suggests to use JedisPool instead.
Or should we be using the direct connection method instead of a connection pool?
Long reading has no NULL checking and many other Primitive readers are defaulting to eg. 0f for both float and Float.
Using JOhm 0.5.0
Test case:
@retention(RetentionPolicy.RUNTIME)
@target(ElementType.FIELD)
public @interface TestAnnotation {}
public class MyEntity {
@Id @TestAnnotation private Integer id;
// etc ...
}
Trying to save the entity gives the exception:
redis.clients.johm.JOhmException: Element annotated @id cannot have any other annotations
at redis.clients.johm.JOhmUtils$Validator.checkValidIdType(JOhmUtils.java:323)
if (type.equals(Boolean.class) || type.equals(boolean.class)) {
return new Boolean(value);
}
Those lines seemed to be missing from convert() method in redis.clients.johm.JOhmUtils.Convertor
We should publish an error dictionary of all the errors that can be thrown as JOhmException's so that users can setup mechanisms to be able to explicitly respond to a particular error scenario.
I think something like a JOhmExceptionMetadata enum can do the job easily. It can encapsulate a running error-number and a message. JOhmException further wraps this object and we ditch the single string constructor in favor of this new one. getMessage() can just delegate to getMetadata().getMessage() in order to not break existing client integrations.
We should also publish this error code:message list on the wiki for our users' easy reference.
@model
public class MyGreatModel {
@reference
@indexed
MyGreatModel relatedMyGreatModel;
}
crashes everything. The problem is that JOhm.get calls, JOhm.fillField which then calls JOhm.get.
We should do something like https://github.com/xetorthio/seek, so we can have a nice search api.
Also we should have between, < and >
Something like:
class User {
@listen(Item.class)
public void onItem() {
}
}
It will be tricky to filter on object fields but we can pass those as an array in the second argument... some thinking to do there.
Is it possible for jOhm to include commands on database such as "select", "flushdb"?
Thanks,
Peter
I just noticed an oversight on our part that is allowing array-indexing to be on by default. In RedisArray's save(), we should first do an if (indexed) before calling indexValue(). I will submit a patch for this.
We need to make JOhm id's longs to reflect changes to incr(). This will be useful over the long run as users accumulate increasing number of objects in their redis repositories. In the short term, it will be a breaking change (mention explicitly in v0.6 release notes).
Johm is no longer compatible with the latest version of Jedis. There are 6 open pull requests that are over 9 months old. If this project has been abandoned it would be better to shut it down or put in the read me the exact version of jedis it's compatible with and that it's no longer being maintained.
I wanted to create an object that just keeps a one-to-many association, so I created model classes like these (getters and setters removed):
@Model
public class Student {
@Id
private Long id;
@CollectionSet(of = Pen.class)
@Indexed
private Set<Pen> pens;
//It appears that at least one attribute class is required
//@Attribute
//private String name;
}
@Model
public class Pen {
@Id
private Long id;
@Attribute
private String color;
}
Using these classes generated an error with JOhm 0.5.0 when you add a Pen to the Student's collection. I was able to work around the problem if I added an attribute to Student and gave it a value.
public class JOhmTest {
public JOhmTest() {
}
@Before
public void setup() throws Exception {
JedisPool jedisPool = new JedisPool(new GenericObjectPool.Config(), "localhost");
JOhm.setPool(jedisPool);
}
/**
* Test of main method, of class JOhmTest.
*/
@Test
public void testMain() {
System.out.println("main");
Pen pen1 = new Pen();
pen1.setColor("blue");
JOhm.save(pen1);
Student student = new Student();
//student.setName("joe");
JOhm.save(student);
Pen pen2 = new Pen();
pen2.setColor("black");
JOhm.save(pen2);
student.getPens().add(pen1);
student.getPens().add(pen2);
int id = (int) student.getId().intValue();
Student foundStudent = JOhm.get(Student.class, id);
System.out.println(foundStudent);
assertEquals(2, foundStudent.getPens().size());
}
}
should be able to store Date fields, probably in redis it could be a timestamp
If you upgrade to use newest Jedis jar, you get lots of "redis.clients.johm.JOhm$1.del([Ljava/lang/String;)Ljava/lang/String;" errors. This happens during a save operation.
To investigate - we need to wire in pipelined jedis commands to improve performance where possible.
Currently, there is no way to delete JOhm indexes even after a model has been deleted via delete(). We need to provide an option to let the user delete the associated indexes if they so desire.
Investigate a potential language independent service-facade for JOhm to see if an optional Thrift, Avro, ProtoBuf binding is feasible for non-Java JOhm users. This needs to be carefully weighed as an optional feature with documented average throughput-loss in benchmark tests.
save() method in redis.clients.johm.JOhm should iterate over every superclass above the root class and add all declared fields .
Class<?> superClazz = model.getClass();
while ((superClazz = superClazz.getSuperclass()) != null) {
fields.addAll(Arrays.asList(superClazz.getDeclaredFields()));
}
get() method should, consequently, recover them in a analog fashion and fill every field:
Class<?> superClazz = clazz;
while ((superClazz = superClazz.getSuperclass()) != null) {
for (Field field : superClazz.getDeclaredFields()) {
fillField(hashedObject, newInstance, field);
}
}
Hi Jonathan and Gaurav,
Is it possible set the expire time for an object like the command "expire" in Redis?
Thanks,
Peter
Inside the "get" method:
value = JOhm.<V> get(valueClazz, Integer.parseInt(valueKey));
I don't know why use Integer.parseInt() but not Long.parseLong(). All the model's @id attribute is long.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.