Migrate data from ASP.Net Membership Provider to System.Web.Providers - asp.net-membership

I am migrating an existing asp.net mvc application to Azure and would like to use the System.Web.Providers for membership.
Is there any existing tool or recipe to Migrate data from the ASP.Net Membership Provider to System.Web.Providers?

There is a post on .NET Web Development and Tools Blog
http://blogs.msdn.com/b/webdev/archive/2012/08/16/migration-for-user-accounts-from-the-sqlmembershipprovider-to-the-universal-providers.aspx
which explains in detail how to move your data and what Web.Config attributes to touch.
basically what you need is a bunch of SQL statements
INSERT INTO dbo.Applications (ApplicationName, ApplicationId, Description)
SELECT ApplicationName, ApplicationId, Description FROM dbo.aspnet_Applications
GO
INSERT INTO dbo.Roles (ApplicationId, RoleId, RoleName, Description)
SELECT ApplicationId, RoleId, RoleName, Description FROM dbo.aspnet_Roles
GO
INSERT INTO dbo.Users (ApplicationId, UserId, UserName, IsAnonymous, LastActivityDate)
SELECT ApplicationId, UserId, UserName, IsAnonymous, LastActivityDate FROM dbo.aspnet_Users
GO
INSERT INTO dbo.Memberships (ApplicationId, UserId, Password,
PasswordFormat, PasswordSalt, Email, PasswordQuestion, PasswordAnswer,
IsApproved, IsLockedOut, CreateDate, LastLoginDate, LastPasswordChangedDate,
LastLockoutDate, FailedPasswordAttemptCount,
FailedPasswordAttemptWindowStart, FailedPasswordAnswerAttemptCount,
FailedPasswordAnswerAttemptWindowStart, Comment)
SELECT ApplicationId, UserId, Password,
PasswordFormat, PasswordSalt, Email, PasswordQuestion, PasswordAnswer,
IsApproved, IsLockedOut, CreateDate, LastLoginDate, LastPasswordChangedDate,
LastLockoutDate, FailedPasswordAttemptCount,
FailedPasswordAttemptWindowStart, FailedPasswordAnswerAttemptCount,
FailedPasswordAnswerAttemptWindowStart, Comment FROM dbo.aspnet_Membership
GO
INSERT INTO dbo.UsersInRoles SELECT * FROM dbo.aspnet_UsersInRoles
GO
You will also have to add passwordCompatMode="Framework20" attribute to membership provider configuration.

Related

Insert batch and Return full object using NamedParameterJdbcTemplate

I am trying to do batch insertion to a table and then read full objects back with their newly generated ids.
private List<Customer> saveCustomer(List<Customer> customerList, Long shopId) {
AtomicInteger index = new AtomicInteger();
SqlParameterSource[] paramsArray = new MapSqlParameterSource[customerList.size()];
for (Customer customer : customerList) {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("shop_id", shopId);
params.addValue("customer_name", pallet.getName());
params.addValue("email", pallet.getEmail());
params.addValue("contact_number", pallet.getContactNumber());
paramsArray[index.getAndIncrement()] = params;
}
String sql =
"INSERT INTO \"Customer\" " +
"(shop_id, customer_name, email, contact_number) " +
"VALUES (:shop_id, :customer_name, :email, :contact_number) " +
"RETURNING id, shop_id, customer_name, email, contact_number ";
return namedParameterJdbcTemplate.getJdbcOperations().query(sql, paramsArray, new CustomerRowMapper());
}
However, this method gives me following error: org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of org.springframework.jdbc.core.namedparam.MapSqlParameterSource. Use setObject() with an explicit Types value to specify the type to use. See stack trace below.
PreparedStatementCallback; bad SQL grammar [INSERT INTO "Customer" (shop_id, customer_name, email, contact_number) VALUES (:shop_id, :customer_name, :email, :contact_number) RETURNING id, shop_id, customer_name, email, contact_number ]; nested exception is org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of org.springframework.jdbc.core.namedparam.MapSqlParameterSource. Use setObject() with an explicit Types value to specify the type to use.
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [INSERT INTO "Customer" (shop_id, customer_name, email, contact_number) VALUES (:shop_id, :customer_name, :email, :contact_number) RETURNING id, shop_id, customer_name, email, contact_number ]; nested exception is org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of org.springframework.jdbc.core.namedparam.MapSqlParameterSource. Use setObject() with an explicit Types value to specify the type to use.
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:101)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1443)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:633)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:669)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:700)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:763)
Everything would be fine if I just wanted to do batch insertion without reading it back. Then I would use
namedParameterJdbcTemplate.batchUpdate(sql, paramsArray);
However, I also need to read inserted values back with their ids but not sure what namedParameterJdbcTemplate method I can use.
TLDR:
I want to do batch insertion and then read inserted rows back using namedParameterJdbcTemplate but cannot find the right method for this. Does namedParameterJdbcTemplate provide batch insertion and selection in a single method?
I got something to work.
private List<Customer> saveCustomer(List<Customer> customerList, Long shopId) {
List<Object[]> batch = customers.stream()
.map(customer -> new Object[] {shopId, customer.getName(), customer.getEmail(), customer.getContactNumber()})
.toList();
String sql = "INSERT INTO \"Customer\" " +
"(shop_id, customer_name, email, contact_number) " +
"values :batch" +
"RETURNING id, shop_id, customer_name, email, contact_number ";
return namedParameterJdbcTemplate.query(sql,
new MapSqlParameterSource("batch", batch),
new CustomerRowMapper());
}
Would love to know if there's a better way
Note: each element of each Object[] is a parameter getting passed and there's a hard cap of 65535 parameters which can be passed at once
As I can see from the methods of namedParameterJdbcTemplate you can't execute batch operation and waiting for something back. What you can do is to execute statement in 1 sql request. Just combine your values if your database supports such syntax:
INSERT INTO Customer (shop_id, customer_name, email, contact_number)
VALUES
(value_list_1),
(value_list_2),
...
(value_list_n);
Then just use JDBCTemplate.update with the GeneratedKeyHolder argument. This might help you: identity from sql insert via jdbctemplate

Query to check if the record exists in Spring Jdbc Template

I am fairly new to spring ,I am looking to check if a certain email id exists in database or not , using Spring Jdbc Template ,I looked here but could'nt find the proper answer .I am looking something like ,SELECT count(*) from table where email=?
Any help will be appreciated.
You can do something as below if you are using jdbctemplate and new version of spring
private boolean isEmailIdExists(String email) {
String sql = "SELECT count(*) FROM table WHERE email = ?";
int count = jdbcTemplate.queryForObject(sql, new Object[] { email }, Integer.class);
return count > 0;
}
queryForObject method of jdbcTemplate accepts the sql query as the first parameter, second argument is an array of objects for the sql query place holders and the third argument is the expected return value from the sql query.
In this case we only have one place holder and hence I gave the second argument as new Object[] { email } and the result we are expecting is a count which is a Integer and hence I gave it as Integer.class
I kind of got this answer from https://www.mkyong.com/spring/jdbctemplate-queryforint-is-deprecated/
You can go through it if you are interested.
private boolean isEmailIdExists(String email) {
return jdbcTemplate.queryForObject("SELECT EXISTS(SELECT FROM table WHERE email = ?)", Boolean.class, email);
}
http://www.postgresqltutorial.com/postgresql-exists/

Issue with writing named sql query with hibernate

I am trying to access database FK using named SQL query with Hibernate, the idea is to query a customer table which contains name, and companyId,etc. CompanyId is the FK for a commpany table. The query I wrote is as follows:
#NamedNativeQuery(name="getcustomer", query="Select CUSTOMER.* from CUSTOMER,COMPANY where CUSTOMER_FIRST_NAME = (?1) and CUSTOMER_LAST_NAME= (?2) and CUSTOMER_COMPANY_ID_FK = (?3) ",resultClass=Customer.class)
The issue I am currently having as follow:
Exception in thread "main" org.hibernate.QueryParameterException:
Position beyond number of declared ordinal parameters. Remember that
ordinal parameters are 1-based! Position: 2 at
org.hibernate.engine.query.spi.ParameterMetadata.getOrdinalParameterDescriptor(ParameterMetadata.java:89)
at
org.hibernate.engine.query.spi.ParameterMetadata.getOrdinalParameterExpectedType(ParameterMetadata.java:109)
at
org.hibernate.internal.AbstractQueryImpl.determineType(AbstractQueryImpl.java:507)
at
org.hibernate.internal.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:479)
at
com.comresource.scrapmetalapp.DAOImpl.CustomerDAOImpl.searchCustomer(CustomerDAOImpl.java:61)
at
com.comresource.scrapmetalapp.ServiceImpl.CustomerServiceImpl.searchCustomer(CustomerServiceImpl.java:39)
at com.comresource.scrapmetalapp.Config.Run.main(Run.java:57)
My DAO implementation is like this:
#Override
public Customer searchCustomer(String fName, String lName, Integer company) {
Session session = sessionFactory.openSession();
return (Customer) session.getNamedQuery("getcustomer").setParameter(1, fName)
.setParameter(2, lName)
.setParameter(3, company)
.uniqueResult();
}
What is the issue here?
For this, I would need to see how you are associating the mapping in your model class, but the query should go like this.
public Customer getMeThatCustomer(String param1, String param2, int foreignkey){
session = getCurrentSession();
org.hibernate.Query query = session.createQuery("From Customer as c where c.name=:param1 and c.lastname=:param2 and c.company.companyid=:foreignkey");
//Note the last parameter, where I have mentioned c.company, in place of
company, there should be the foregin key association and then the primary key in java class.
query.setParameter("param1",param1);
query.setP...er("param2",param2);
quer.....("companyid",companyid);
return (Customer) query.uniqueResult();
}
So, try it out, let me know if there is any problem

iBatis.NET to insert record with Oracle stored procedure, return record ID

I am attempting to insert a record in an Oracle table with a Function, which would be called through iBatis.NET. Function works as expected in Oracle when called directly.
I have tried using <statement> and <insert> SqlMap but I can't get iBatis.NET to call the function, and Oracle doesn't support returning anything from Stored Procedure.
I would need to pass properties of my object as parameters to a function/sproc and get back the ID of this new record.
What would be a good combination of iBatis.NET call / SQLMap / Sproc or Function signature in Oracle?
The documentation only has examples of in-line SQL and I can only use sprocs.
Due to the number of properties in real objects, the hash-map and number of parameters is in the 30+.
Ideally I would be able to do this (doesn't work):
<procedure id="InsertPerson" parameterClass="BOM.Person">
TestDB.PERSON_PKG.InsertPerson(#Name#, #Age#)
</procedure>
Domain object:
public class Person
{
int ID { get; set; }
string Name { get; set; }
decimal Age { get; set; }
}
iBatis.NET call:
int personID = mapper.Insert("InsertPerson", person);
Oracle Stored Procedure:
FUNCTION InsertPerson(
p_Name IN Persons.Name%TYPE,
p_Age IN Persons.Age%TYPE,
) RETURN NUMBER
IS
NEW_ID Persons.ID%TYPE;
BEGIN
SELECT Persons_SEQ.NEXTVAL INTO NEW_ID FROM DUAL; /* Get new ID*/
INSERT INTO Persons(ID, Name, Age)
SELECT NEW_ID, p_Name, p_Age from dual; /* Insert record */
COMMIT;
RETURN NEW_ID;
END;
In case this helps someone else, I was unable to find a workaround to my problem.
I ended up implementing this as a Stored Procedure which takes input parameters for all fields to be inserted in to a table, and one output parameter which returns the unique ID generated by sequence.
After executing mapper.Insert(...) I simply read the output parameter and return it.
C#:
mapper.BeginTransaction(System.Data.IsolationLevel.Serializable);
// Add new Record
Hashtable param = new Hashtable();
param.Add("ID", user.ID); // Output
param.Add("DeptID", user.DeptID);
param.Add("RightID", user.RightID);
mapper.Insert("AddUserRight", param);
user.ID = Convert.ToInt32(param["ID"]);
MyBATIS map:
<?xml version="1.0" encoding="utf-8" ?>
<sqlMap namespace="CCP" xmlns="http://ibatis.apache.org/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<statements>
<procedure id="AddUserRight" parameterMap="AddUserRight-param">
Database.USER_PKG.ADDUSERRIGHT
</procedure>
</statements>
<parameterMaps>
<parameterMap id="AddUserRight-param">
<parameter property="ID" column="ID" direction="Output" />
<parameter property="DeptID" column="DeptID" direction="Input" />
<parameter property="RightID" column="RightID" direction="Input" />
</parameterMap>
</parameterMaps>
</sqlMap>
Sproc (Oracle):
PROCEDURE AddUserRight(
ID OUT USERRIGHTS.USERID%TYPE,
DEPTID IN USERRIGHTS.DEPTID%TYPE,
RIGHTID IN USERRIGHTS.RIGHTID%TYPE)
IS
BEGIN
SELECT USERRIGHTS_UNQ_SEQ.NEXTVAL INTO ID FROM DUAL;
INSERT INTO USERRIGHTS(ID, DEPTID, RIGHTID)
VALUES (ID, DEPTID, RIGHTID);
END;

When does a role get enabled for a user in Oracle 10g?

I use ADO.NET from C# 4 in order to set up a test context for a component.
I execute the following SQL as sysdba:
new[]
{
"create user \"{0}\" identified externally default tablespace USER_DATA temporary tablespace TEMP profile DEFAULT"
.FormatWith( Config.QualifiedUserName ),
"create role {0}"
.FormatWith( Config.RoleName ),
"grant {0} to \"{1}\""
.FormatWith( Config.RoleName, Config.QualifiedUserName ),
"insert into doc.application( id, name ) values( {0}, '{1}' )"
.FormatWith( Config.AppId, Config.AppName ),
"insert into doc.appl_role( application, role, description ) values( {0}, '{1}', '{2}' )"
.FormatWith( Config.AppId, Config.RoleName, Config.RoleDescription ),
"create table {0}.{1} ( ID number primary key, VERSION number, NAME varchar(100) )"
.FormatWith( Config.TestSchema, Config.TestTable ),
"insert into {0}.{1} (ID, VERSION, NAME) values ('{2}', '{3}', '{4}')"
.FormatWith( Config.TestSchema, Config.TestTable, Config.TestRowId, 1, Config.TestRowName ),
"grant select, insert, update, delete on {0}.{1} to {2}"
.FormatWith( Config.TestSchema, Config.TestTable, Config.RoleName ),
"grant create session to \"{0}\""
.FormatWith( Config.QualifiedUserName )
}
and the Config class looks like so:
public struct Config
{
public const Int32 TestRowId = 1;
public const Int32 AppId = 99999;
public const String AppName = "OraceUtils";
public const String RoleName = "ORACLE_UTILS_BASE";
public static readonly String RoleDescription = "For testing {0}".FormatWith( AppName );
public static readonly String QualifiedUserName = #"{0}\{1}".FormatWith( Domain, UserName );
public const String DataSource = "TESTDB";
public const String Domain = "BI";
public const String UserName = "ORACLE_TEST_USER";
public const String UserPassword = [for my eyes only];
public const String TestSchema = "CI";
public const String TestTable = "ROLE_PROVIDER_TEST_TABLE";
public const String TestRowName = "Arne And";
}
From what I've read, just granting a role to a user doesn't enable it. However, after executing the SQL above, the user BI\ORACLE_TEST_USER can use the table ROLE_PROVIDER_TEST_TABLE just fine. The role ORACLE_UTILS_BASE also shows in SESSION_ROLES.
If I issue "SET ROLES" afterwards, the aforementioned user can't access the table.
I thought it was the other way around, i.e. that the user wouldn't have access until she issues "SET ROLES ORACLE_UTILS_BASE, [any other roles]".
When a user connects to the DB, all their default roles are enabled. You can change which roles are defaults with the synthax:
ALTER USER <user> DEFAULT ROLE <role>
<role> can be either a role name or the keywords ALL or NONE
When you grant a role to a user it becomes a default role (i-e the user doesn't have to activate it with SET ROLE <role> when they connect).

Resources