Giter VIP home page Giter VIP logo

johm's Introduction

JOhm

JOhm is a blazingly fast Object-Hash Mapping library for Java inspired by the awesome Ohm. The JOhm OHM is a modern-day avatar of the old ORM's like Hibernate with the difference being that we are not dealing with an RDBMS here but with a NoSQL rockstar.

JOhm is a library for storing objects in Redis, a persistent key-value database. JOhm is designed to be minimally-invasive and relies wholly on reflection aided by annotation hooks for persistence. The fundamental idea is to allow large existing codebases to easily plug into Redis without the need to extend framework base classes or provide excessive configuration metadata.

Durable data storage is available via the Redis Append-only file (AOF). The default persistence strategy is Snapshotting.

What can I do with JOhm?

JOhm is still in active development. The following features are currently available:

  • Basic attribute persistence (String, Integer, etc...)
  • Auto-numeric Ids
  • References
  • Arrays
  • Indexes
  • Deletion
  • List, Set, SortedSet and Map relationship
  • Search on attributes, arrays, collections and references

Stay close! It is growing pretty fast!

How do I use it?

You can download the latest build at http://github.com/xetorthio/johm/downloads

And this is a small example (getters and setters are not included for the sake of simplicity):

@Model
class User {
    @Id
    private Long id;
	@Attribute
	private String name;
	@Attribute
	@Indexed
	private int age;
	@Reference
	@Indexed
	private Country country;
	@CollectionList(of = Comment.class)
	@Indexed
	private List<Comment> comments;
	@CollectionSet(of = Item.class)
	@Indexed
	private Set<Item> purchases;
	@CollectionMap(key = Integer.class, value = Item.class)
    @Indexed
    private Map<Integer, Item> favoritePurchases;
    @CollectionSortedSet(of = Item.class, by = "price")
    @Indexed
    private Set<Item> orderedPurchases;
    @Array(of = Item.class, length = 3)
    @Indexed
    private Item[] threeLatestPurchases;
}

@Model
class Comment {
    @Id
    private Long id;
	@Attribute
	private String text;
}

@Model
class Item {
    @Id
    private Long id;
	@Attribute
	private String name;
}

Initiating JOhm: jedisPool = new JedisPool(new Config(), "localhost"); JOhm.setPool(jedisPool);

Creating a User and persisting it:

User someOne = new User();
someOne.setName("Someone");
someOne.setAge(30);
JOhm.save(someOne);

Loading a persisted User:

User storedUser = JOhm.get(User.class, 1);

Deleting a User:

JOhm.delete(User.class, 1);

Search for all users of age 30:

List<User> users = JOhm.find(User.class, "age", "30");

Model with a reference:

User someOne = new User();
...
JOhm.save(someOne);

Country someCountry = new Country();
...
JOhm.save(country);

someOne.setCountry(someCountry);

Model with a list of nested models:

User someOne = new User();
...
JOhm.save(someOne);

Comment aComment = new Comment();
...
JOhm.save(aComment);

someOne.getComments.add(aComment);

Model with a set of nested models:

User someOne = new User();
...
JOhm.save(someOne);

Item anItem = new Item();
...
JOhm.save(anItem);

someOne.getPurchases.add(anItem);

For more usage examples check the tests.

And you are done!

License

Copyright (c) 2010 Gaurav Sharma and Jonathan Leibiusky

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

johm's People

Contributors

gsharma avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

johm's Issues

avoid to parse classes and work on model at runtime

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.

JOhm doesn't support Jedis 2.0.0

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.

Getting error redis.clients.johm.JOhmException: java.lang.IllegalArgumentException: Can not set java.lang.Long field User.id to java.lang.Integer

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;
    }
}

Does JOhm support ShardedJedisPool?

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?

what 's the reason of "nest.cat("all").sadd(String.valueOf(JOhmUtils.getId(model)));" ?

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"

the Integer.parseInt in RedisMap

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.

add support for pub/sub

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.

Expire time for an object

Hi Jonathan and Gaurav,
Is it possible set the expire time for an object like the command "expire" in Redis?
Thanks,
Peter

Cannot add non-johm annotations to @Id field

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)

Research non-Java bindings for JOhm API

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.

Support non-Model values for CollectionMap

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.

Publish JOhm error-dictionary

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.

Out of date. Abandoned?

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.

Connection pool gets exhausted after a while

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

Support mapping of attributes in all classes of the inheritance hierarchy

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);
            }
        }

At least one attribute with a value appears to be required

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());
    }
}

Allow multiple instances of JOhm

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.

Bug - array indexing on by default

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.

JOhm to support long id's in line with the update to Jedis incr()

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).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.