How to get a recordid from OrientDB on insert? - insert

OrientDB question...
Does anyone know how I can get the recordId after an insert:
db.save(person)
I tried below on the Person POJO:
#Id
private Object id;
but the id field was null after the save. I've googled and googled to no avail. I just need to insert an object, then get the recordid that orientdb generates.

Define field in pojo:
#Id
private Object rid;
public Object getRid() {
return rid;
}
When save:
YourClass proxy = db.save(yourClassInstance);
Object rid = proxy.getRid();

I got it to work using ODocuments instead of POJOs (which works for my project). Code sample:
ODatabaseDocumentTx db = null;
ODocument doc = null;
db = new ODatabaseDocumentTx("local:" + System.getProperty("user.home") + "/testDB");
db.create();
doc = new ODocument("Person");
doc.field("name", "Peter");
doc.save();
String rid = doc.getIdentity().toString();
List<ODocument> results = db.query(new OSQLSynchQuery<ODocument>("select from " + rid));
for (ODocument aDoc : results) {
System.out.println(aDoc.field("name"));
}
db.close();

It's just simple here is the code:
//insertquery will be the sql statement you want to insert
ODocument result=db.command(new OCommandSQL(insertquery)).execute();
System.out.println(result.field("#rid"));

Alternatively you can make use of getRecordByUserObject() of OObjectDatabaseTx,
OObjectDatabaseTx db = new OObjectDatabaseTx("local:" + System.getProperty("user.home") + "/testDB");
ODocument oDocument = db.getRecordByUserObject( person, true );
oDocument.save();
String rid = oDocument.getIdentity().toString();

If you already have access to your proxy object from the save, you can totally do a cool cast on it to get the underlying ODocument object which has a record ID (Identity).
Person proxyPerson = db.save(person);
ODocument oDocument = ((OObjectProxyMethodHandler)((ProxyObject)proxyPerson).getHandler()).getDoc();
person.setId(oDocument.getIdentity().toString());

Related

Spring JDBC : Inconsistent results when performing Order By

Any help would be greatly appreciated. I am working on a project using Spring JDBC for data access and am performing a simple query with an order by column expression, I am currently getting inconsistent results meaning the order by doesn't seem to be working. I have tried more than one database still no avail.
String sql = "select * from account where upper(name) like upper(:query) order by name asc";
MapSqlParameterSource params = new MapSqlParameterSource().addValue("query", "%" + query + "%");
List<Account> accountsSearched = namedParameterJdbcTemplate.query(sql, params, new BeanPropertyRowMapper<Account>(Account.class));
Any ideas what could be the issue?
So the problem is not within your SQL code, but problem exist in search method implementation
Existing Code
public List<Account> search(String uncleanedQuery, int offset) {
String query = uncleanedQuery.replaceAll("([-+.^:,])","");
String sql = "select * from account where upper(name) like upper(:query) order by name asc";
MapSqlParameterSource params = new MapSqlParameterSource().addValue("query", "%" + query + "%");
List<Account> accountsSearched = namedParameterJdbcTemplate.query(sql, params, new BeanPropertyRowMapper<Account>(Account.class));
Set<Account> accountSearchSet = new HashSet<Account>(accountsSearched);
List<Account> accounts = new ArrayList<Account>(accountSearchSet);
return accounts;
}
In the above code, we are fetching data correctly but assigning it to HashSet. HashSet does not respect ordering by name and generates random order for Account, due to which you are getting random order every time.
Solution 1:
There is no reason, you actually need Set. Using set just making your program slow. If you want to get DISTINCT data then modify SQL query.
public List<Account> search(String uncleanedQuery, int offset) {
String query = uncleanedQuery.replaceAll("([-+.^:,])","");
String sql = "select * from account where upper(name) like upper(:query) order by name asc";
MapSqlParameterSource params = new MapSqlParameterSource().addValue("query", "%" + query + "%");
List<Account> accountsSearched = namedParameterJdbcTemplate.query(sql, params, new BeanPropertyRowMapper<Account>(Account.class));
return accountsSearched;
}
Solution 2:
Still, you want to go with your approach then change code to use TreeSet and order based on the name
public List<Account> search(String uncleanedQuery, int offset) {
String query = uncleanedQuery.replaceAll("([-+.^:,])", "");
System.out.println("Search Query Called");
String sql = "select * from account where upper(name) like upper(:query) order by name";
MapSqlParameterSource params = new MapSqlParameterSource().addValue("query", "%" + query + "%");
List<Account> accountsSearched = namedParameterJdbcTemplate.query(sql, params,
new BeanPropertyRowMapper<Account>(Account.class));
Comparator<Account> comp = new Comparator<Account>() {
#Override
public int compare(Account a1, Account a2) {
return a1.getName().compareTo(a2.getName());
}
};
SortedSet<Account> accountSearchSet = new TreeSet<Account>(comp);
accountSearchSet.addAll(accountsSearched);
List<Account> accounts = new ArrayList<Account>(accountSearchSet);
return accounts;
}

Linq in C# using IEnumerable

Appearently, I got an error if using the following code. It said:
Cannot implicity converrt type System.Linq.IQueryable<AnonymousType> to System.Collection.Generic.IEnumerable.
Please advise how I can fix this?
public IEnumerable<Session> GetAllListDetailConsumer(string refId)
{
ObjectQuery<Session> sessions = db.Sessions;
ObjectQuery<SessionsList> sessionsLists = db.SessionsList;
var query =
from s in sessions
join sList in sessionsLists on s.ReferralListID equals sList.ReferralListID
where s.ReferralListID == new Guid(refId)
select new SessionConsumerList
{
ReferralListID = s.ReferralListID,
SessionServerId = s.SessionServerID,
ApplicationID = s.ApplicationID,
// ...
ConsumerID = sList.ConsumerID,
ConsumerFirstName = sList.ConsumerFirstName,
ConsumerFamilyName = sList.ConsumerFamilyName,
// ...
};
return query.ToList();
}
You are selecting using select new, which would create an anonymous type, you need to project to class Session in your query like.
select new Session
{
....
But remember if your Session class is a representing a table in your database/data context, then you can't project to that class, instead you may have to create a temporary class and project the selection to that class.
EDIT (Since the question now has been edited)
Now you are selecting new SessionConsumerList and you are returning IEnumerable<Session>, you need to modify method signature to return IEnumerable<SessionConsumerList>
Why not separate the creation of the SessionConsumerList in another method? Makes the code a lot cleaner. Like this:
public static SessionConsumerList CreateSessionConsumerList(
Session s,
SessionsList sList)
{
return new SessionConsumerList
{
ReferralListID = s.ReferralListID,
SessionServerId = s.SessionServerID,
ApplicationID = s.ApplicationID,
// ...
ConsumerID = sList.ConsumerID,
ConsumerFirstName = sList.ConsumerFirstName,
ConsumerFamilyName = sList.ConsumerFamilyName,
// ...
};
}
And then:
var query =
from s in sessions
join sList in sessionsLists on s.ReferralListID equals sList.ReferralListID
where s.ReferralListID == new Guid(refId)
select CreateSessionConsumerList(s, sList);

Save Entity Framework Linq Query to database

I was wondering if we can convert a Linq Query on the Entity Framework and save the query to the database by converting it to an Expression Tree and Serializing. Can someone please help me on this and point me in a right direction whether this can be done or not. Any help is greatly appreciated on this.
Thanks,
Ajay.
i released a library for that purpose just yesterday. Serialize.Linq. It serializes linq expressions to xml, json or binary.
using System.Linq.Expressions
using Serialize.Linq.Extensions;
Expression<Func<Person, bool>> query = p => p.LastName == "Miller"
&& p.FirstName.StartsWith("M");
Console.WriteLine(query.ToJson());
Console.WriteLine(query.ToXml());
You could turn the query into a string and then save the string.
This is from an answer by Nick Berardi:
var result = from x in appEntities
where x.id = 32
select x;
var sql = ((System.Data.Objects.ObjectQuery)result).ToTraceString();
The sql generated by the query could be stored and re-used.
Use Sprint.Filter.OData. It converts a Func<T,bool> into string and back to code.
Sample:
public class TestSprintOData
{
public static void Run()
{
// Parse a Func into string
var query = Filter.Serialize<User>(u => u.IsActive && u.Email.Contains("#gmail.com"));
// It'll generate the string "IsActive and substringof('#gmail.com', Email)"
// Convert back to Expression, perhaps on server
var query2 = Filter.Deserialize<User>(query);
// Compiles to Func, so you can use as delegate to Where
var f = query2.Compile();
var list = new List<User>
{
new User{Name="Johnny", IsActive = true, Email = "johnny#gmail.com"},
new User{Name="abc", IsActive = false, Email = ""},
new User{Name="dude", IsActive=true, Email = "dude#gmail.com"}
};
var result = list.Where(f);
}
}
class User
{
public string Name;
public string Phone;
public string Login;
public string Email;
public bool IsActive;
}
You can also use it as a Nuget Package
You may want to consider using Entity SQL rather than LINQ in this case. Entity SQL is a string query that works against your EF conceptual model rather than directly against the database.

ef4 poco,how get id after insert?

I am inserting a document and i want references id of document to a part of this
document...but the code is autoincrement, and i am using poco. how i can get
back the code of insert file?
ArquivoDTO file = new ArquivoDTO();
file.NomeArquivo = fileName;
file.TipoArquivo = fileType;
file.TamanhoArquivo = fileSize;
var context = new PROGISContext();
ArquivoRepository arquivoRepository = new ArquivoRepository(context);
arquivoRepository.IncluirArquivo(file); //insert file
ParteArquivoDTO part = new ParteArquivoDTO(); //create a part
part.CodArquivo = file.CodArquivo; // here id of inserted file
Something like this
[Key, DatabaseGenerated( DatabaseGeneratedOption.Identity )]
public Guid Identifier { get; protected set; }
However you won't get the I'd untill you call SaveChanges()
It's kind of hard to say what's the problem with this code sample alone, but are you calling SubmitChanges() on your DataContext in arquivoRepository.IncluirArquivo(file)?
If you are, and the CodArquivo property of your ArquivoDTO class it correctly configured to be an auto increment ID, then the property should get updated automatically after SubmitChanges().

ODP.NET and parameters

I have built a common app that works with PostgreSQL and should work on Oracle.
However i'm getting strange errors when inserting records through a parametrized query.
My formatted query looks like this:
"INSERT INTO layer_mapping VALUES (#lm_id,#lm_layer_name,#lm_layer_file);"
Unlike Npgsql which documents how to use the parameters, i could not found how Oracle "prefers" them to be used. I could only find :1, :2, :3, for example.
I do not wanto use sequential parameters, i want to use them in a named way.
Is there a way to do it? Am i doing something wrong?
Thanks
You can use named parameters with ODP.NET like so:
using (var cx=new OracleConnection(connString)){
using(var cmd=cx.CreateCommand()){
cmd.CommandText="Select * from foo_table where bar=:bar";
cmd.BindByName=true;
cmd.Parameters.Add("bar",barValue);
///...
}
}
I made this lib https://github.com/pedro-muniz/ODPNetConnect/blob/master/ODPNetConnect.cs
so you can do parameterized write and read like this:
ODPNetConnect odp = new ODPNetConnect();
if (!String.IsNullOrWhiteSpace(odp.ERROR))
{
throw new Exception(odp.ERROR);
}
//Write:
string sql = #"INSERT INTO TABLE (D1, D2, D3) VALUES (:D1, :D2, :D3)";
Dictionary<string, object> params = new Dictionary<string, object>();
params["D1"] = "D1";
params["D2"] = "D2";
params["D3"] = "D3";
int affectedRows = odp.ParameterizedWrite(sql, params);
if (!String.IsNullOrWhiteSpace(odp.ERROR))
{
throw new Exception(odp.ERROR);
}
//read
string sql = #"SELECT * FROM TABLE WHERE D1 = :D1";
Dictionary<string, object> params = new Dictionary<string, object>();
params["D1"] = "D1";
DataTable dt = odp.ParameterizedRead(sql, params);
if (!String.IsNullOrWhiteSpace(odp.ERROR))
{
throw new Exception(odp.ERROR);
}
Notes: you have to change these lines in ODPNetConnect.cs to set connection string:
static private string devConnectionString = "SET YOUR DEV CONNECTION STRING";
static private string productionConnectionString = "SET YOUR PRODUCTION CONNECTION STRING";
And you need to change line 123 to set environment to dev or prod.
public OracleConnection GetConnection(string env = "dev", bool cacheOn = false)

Resources