GAE数据存储与GWT,使更友好/更小的密钥 [英] GAE Datastore with GWT, making more friendly/smaller keys

查看:98
本文介绍了GAE数据存储与GWT,使更友好/更小的密钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用GWT,GAE并使用JPA作为我的ORM。我有一个问题,GAE生成的密钥太大,无法在带有RequestFactory的移动设备上使用。当转换为字符串时,由于ID / KEY的大小,小列表中的数据量是压倒性的。



我为字符串使用字符串,以便处理继承。

 <$ c $ b $ @ @ 
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Extension(vendorName =datanucleus,key =gae.encoded-pk,value =true)
保护String键;

这会创建一个非常长的示例agxzbWFydGJhcnNpdGVyFAsSDUVzdGFibGlzaG1lbnQYuAIM的键并由于存储对象类型而变得更大父母在关键。

我需要一种方法来创建一个更小的唯一ID,但仍然有能力处理GAE中的继承。我尝试了Long作为@Id /键,但由于内置在String / Key键中的关系,无法在我的对象上使用@OneToMany关系。



另一种选择是为每个类创建一个序列,并为该id使用Long属性。下面有一个例子,但我不确定如何处理应用程序引擎中生成的Long序列。

@GeneratedValue
private long friendlyClassSpecificKey;

任何建议将不胜感激。如果除了为每个类类型使用序列之外还有其他选项,我很感兴趣,但如果没有,是否有创建特定类的序列的示例(不是@ID)?

解决方案

我想出了一个很好的小键盘解决方案。我认为最好的方法是将jpa / jdo 2用于具有无主关系的应用程序引擎。这样你就可以使用他们的类型从(Long)id中获取密钥,而不必使用父亲关系。



这是基本的datastore对象,并注意到我正在使用应用程序引擎密钥。

  @Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class DatastoreObject {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY )
私钥键;

public Long getId(){
return key.getId();
}

}

这个类将使用@未知属性在jpa 2中受支持,以便库存密钥不包含父级建立密钥。否则,你将不得不传递父ID,并将其解析为基于类型的密钥。这是因为在一个拥有的关系中,子密钥也包含父密钥。

  @Entity 
public class Establishment extends DatastoreObject {

@未知
@OneToOne(cascade = CascadeType.ALL)
私有库存清单;






然后在我的dao基类中,我使用类 p>

  public class DaoBase< T extends DatastoreObject> {

protected Class< T> clazz中;

@SuppressWarnings(unchecked)
public DaoBase(){
clazz =(Class< T>)((ParameterizedType)getClass()
.getGenericSuperclass ))getActualTypeArguments()[0];
}


/ **
*通过它缩短的长ID来查找对象
* @param id
* @return
* @throws EntityNotFoundException
* /
public T find(Long id){
if(id == null){
return null;
}
EntityManager em = ThreadLocalPersistenceManager.getEntityManager();

Key key = getKey(id);

T obj = em.find(clazz,key);
return obj;
}

protected KeyKey(Long id){
return KeyFactory.createKey(clazz.getSimpleName(),id);
}
}


I am currently working with GWT, GAE and using JPA as my ORM. I have an issue where the keys that GAE is generating are too large reasonably to be used on a mobile device with RequestFactory. The amount of data in a small list is overwhelming due to the size of the ID/KEY when converted to String.

I am using String for my key's so that I can handle inheritence.

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")  
  protected String key;

This creates a key that is very long example "agxzbWFydGJhcnNpdGVyFAsSDUVzdGFibGlzaG1lbnQYuAIM" and gets larger due to storing object type and parent in the key.

I need a way to create a smaller unique id but still have the ability to handle inheritence in GAE. I tried Long as the @Id/key but was not able to use a @OneToMany relationship on my objects due to the relationship that is built into the String/Key key.

The other option is to create a sequence for each class and use a Long property for that id. There is an example below but I am not sure how to handle a generated Long sequence in app engine.

@GeneratedValue private Long friendlyClassSpecificKey;

Any advice would be appreciated. If there is another option other than using the sequence for each class type I am interested but if not is there an example of creating a sequence (That is not the @ID) for a specific class?

解决方案

I came up with a good solution for smaller keys. I think the best way to do this cleanly is to use jpa/jdo 2 for app engine with an unowned relationship. This way you can fetch the keys from (Long) id using just their type and not have to use the parent relationship.

This is the base datstore object and notice I am using the app engine key.

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class DatastoreObject {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Key key;

  public Long getId() {
    return key.getId();
  }

}

This class will use the @Unowned attribute supported in jpa 2 so that the inventory's key does not contain the parent establishment key. Otherwise you would have to pass the parent id in also and resolve that to a key based on type. This is because in an owned relationship the child key contains the parent key also.

@Entity
public class Establishment extends DatastoreObject {

    @Unowned
    @OneToOne(cascade = CascadeType.ALL)
    private Inventory inventory;

}

Then in my dao base class I use the class

public class DaoBase<T extends DatastoreObject> {

protected Class<T> clazz;

    @SuppressWarnings("unchecked")
    public DaoBase() {
        clazz = (Class<T>) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];
    }


    /**
     * Find an object by it's shortened long id
     * @param id
     * @return
     * @throws EntityNotFoundException
     */
    public T find(Long id) {
        if (id == null) {
            return null;
        }
        EntityManager em = ThreadLocalPersistenceManager.getEntityManager();

        Key key = getKey(id);

        T obj = em.find(clazz, key);
        return obj;
    }

    protected Key getKey(Long id) {
        return KeyFactory.createKey(clazz.getSimpleName(), id);
    }
}

这篇关于GAE数据存储与GWT,使更友好/更小的密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆