我刚刚开始探索PlayOrm并尝试运行网络上可用的基本代码来插入和读取数据。当我插入数据时,一切似乎都工作正常,但在读取相同的数据时,它返回错误的行数。例如。如果我插入3条记录,有时会得到0条记录,有时会返回所有记录。
按照我使用的代码:
用于插入/读取数据的类:
@NoSqlEntity
@NoSqlQueries({
@NoSqlQuery(name="findByLastName", query="PARTITIONS t('lastName',:lastName) select * FROM TABLE as t"),
@NoSqlQuery(name="findByName", query="PARTITIONS e('name',:name) select * FROM TABLE as e")
})
public class User {
@NoSqlId
private String id;
@NoSqlPartitionByThisField
private String name;
@NoSqlIndexed
private int age;
@NoSqlPartitionByThisField
@NoSqlIndexed
private String lastName;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
/*
* Queries:
* @NoSqlQuery(name="findByLastName", query="PARTITIONS t('lastName',:lastName) select * FROM TABLE as t"),
* @NoSqlQuery(name="findByName", query="PARTITIONS e('name',:name) select * FROM TABLE as e")
*/
public static List<User> findByLastName(NoSqlEntityManager mgr, String lastName) {
Query<User> query = mgr.createNamedQuery(User.class, "findByLastName");
System.out.println("Using last name "+lastName);
query.setParameter("lastName", lastName);
return query.getResultList(0, 100);
}
public static List<User> findByName(NoSqlEntityManager mgr, String name) {
Query<User> query = mgr.createNamedQuery(User.class, "findByName");
System.out.println("Using name "+name);
query.setParameter("name", name);
return query.getResultList(0, 100);
}
}
使用此类的代码:
import java.awt.List;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import com.alvazan.orm.api.base.Bootstrap;
import com.alvazan.orm.api.base.DbTypeEnum;
import com.alvazan.orm.api.base.NoSqlEntityManager;
import com.alvazan.orm.api.base.NoSqlEntityManagerFactory;
import com.netflix.astyanax.retry.SleepingRetryPolicy;
public class Example {
private static NoSqlEntityManager mgr;
public static void main(String[] args) {
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(Bootstrap.AUTO_CREATE_KEY, "create");
/*
* Bootstrap.createAndAddBestCassandraConfiguration(properties, clusterName, keyspace, seeds);
* NoSqlEntityManagerFactory factory = Bootstrap.create(DbTypeEnum.CASSANDRA, properties,null,null);
*/
NoSqlEntityManagerFactory factory = Bootstrap.create(DbTypeEnum.IN_MEMORY, properties,null,null);
mgr = factory.createEntityManager();
String file_to_use = userData;
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
System.out.println("Starting inserts with file "+file_to_use+" at "+sdf.format(Calendar.getInstance().getTime()));
BufferedReader CSVFile = null;
try {
CSVFile = new BufferedReader(new FileReader(file_to_use));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String dataRow = null;
try {
dataRow = CSVFile.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // Read the first line of data.
int i = 0;
while (dataRow != null){
String[] dataArray = dataRow.split(",");
User user = new User();
user.setName(dataArray[0]);
user.setAge(Integer.parseInt(dataArray[1]));
user.setLastName(dataArray[2]);
System.out.println("Inserting Values "+dataArray[0]+" "+dataArray[1]+" "+dataArray[2]);
mgr.flush();
try {
dataRow = CSVFile.readLine();
} catch (IOException e) {
e.printStackTrace();
}
}
java.util.List<User> result;
System.out.println("#### By LastName ####");
result = User.findByLastName(mgr, "Freida");
System.out.println("Result Size: "+ result.size());
System.out.println("#### By Time ####");
result = User.findByName(mgr, "John");
System.out.println("Result Size: "+ result.size());
}
}
用户数据的内容:
John,17,Freida
Jim,18,Freida
Jam,19,Freida
Johny,20,Freida
Jen,21,Freida
答案 0 :(得分:1)
编辑:这是PlayOrM中一个非常具体的错误。最新的https://github.com/deanhiller/playorm/commit/22d50a12667d03fd2c4683abeb59a4822420a4ce
是最近提交的修复程序只有在同一列上同时使用@NoSqlPartionedBy和@NoSqlIndexed两次时才会发生这种情况。一种解决方法是在where子句(任何东西)中放置一些东西,它每次都会使用特定的索引(基于where子句中的列)。或者只需使用修复程序获取最新代码。
我不确定你应该使用分区。在您的示例中,您以两种方式对表进行分区.... name和lastName。在一种情况下,具有相同名称的所有行都在同一分区中。在另一种情况下,具有相同lastName的所有行都在同一分区中。您只能查询单个分区。所以想象你有名字
dean
mike
joe
这些是3个不同的分区,您可以向任何人查询。你可以查询“给我所有的人在last = dean中使用lastname = smith”或者你可以查询给我所有在分区= mike中使用lastname = smith的人“
想象一下,你也有了lastNames
smith
black
obama
你在这里有3个分区,你可以查询“给我所有名字= dean in the partition = smith的人”或“给我所有名字= dean in the partition = black”的人
如果你想让事情变得更容易,那就去掉所有的@NoSqlPartitionByField吧,这样就根本不进行分区。
基本上,通过分区,您可以查询单个分区。每个分区都是它自己的索引。这就是为什么它可以扩展,因为你拥有X百万行的无限分区。但是,您不能在分区中拥有无限行。
我猜很多但是你的例子只插入一行,而你声称要插入3行,我希望你的代码在两种情况下都返回1行。您的查询要求返回lastName =“Frieda”的分区的所有行,然后返回分区中name =“John”的所有行,并且因为您存储了一个包含两者的对象,即行最终应该进入的分区。 ..这对我们来说已经在生产中使用了,我们也没有任何问题。
如果您有更多信息,请参阅执行3次插入的代码,而不仅仅是这一次。
迪安