XmlSerializer and XmlException - Root element is missing - xml-serialization

Why doesn't the following deserialize? The exception is shown below. Note that I'm using new streams serialization and deserialization to avoid "end of stream" errors. I'm also using new XmlSerializer instances to avoid similar problems there.
Serialization works fine. I've reviewed MANY of the similarly-named questions to no avail.
Exception:
System.InvalidOperationException was unhandled
Message=There is an error in XML document (0, 0).
Source=System.Xml
StackTrace:
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
at TestSerilalization.Program.Main(String[] args) in D:\MyDocs\Projects\dsb\Src\Apps\RecipeMgr\Other\TestSerlialization\Program.cs:line 45
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.Xml.XmlException
Message=Root element is missing.
Source=System.Xml
LineNumber=0
LinePosition=0
SourceUri=""
StackTrace:
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XmlTextReader.Read()
at System.Xml.XmlReader.MoveToContent()
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderClass1.Read4_Class1()
InnerException:
Code:
static void Main(string[] args)
{
XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer( typeof( Class1 ), "http://xxx" );
Class1 c1 = new Class1();
FileStream strm = File.Create( "d:\\temp\\classes.xml" );
xmlSerializer.Serialize( strm, c1 );
strm.Close();
Class1 c2 = null;
FileStream strm2 = File.Create( "d:\\temp\\classes.xml" );
XmlSerializer xmlSerializer2 = new System.Xml.Serialization.XmlSerializer( typeof( Class1 ), "http://xxx" );
c2 = (Class1)xmlSerializer2.Deserialize( strm2 );
strm2.Close();
}
public class Class1
{
public Class1()
{
m_Class2 = new Class2();
}
public Class2 class2
{
get { return m_Class2; }
set { m_Class2 = value; }
}
private Class2 m_Class2;
}
public class Class2
{
public Class2()
{
m_Int = 999;
m_Str = "sdfsdfsdsd";
}
public int getInt
{
get { return m_Int; }
set { m_Int = value; }
}
public string getStr
{
get { return m_Str; }
set { m_Str = value; }
}
private int m_Int;
private string m_Str;
}
The generated xml:
<?xml version="1.0"?>
<Class1 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://xxx">
<class2>
<getInt>999</getInt>
<getStr>sdfsdfsdsd</getStr>
</class2>
</Class1>

File.Create creates a new blank file.
Therefore, you're reading an empty file.
You probably want File.Open.

Related

mybatis interceptor throw Reflection exception affects cpu performence

I had implement a interceptor of myabtis. but we found a problem, execute interceptor lead to throw so many IllegalAccessException, it affects cpu performence
Shown below is where the problem is, why did not check access permision of feild befor executed code "field.get(target)".
public class GetFieldInvoker implements Invoker {
private final Field field;
public GetFieldInvoker(Field field) {
this.field = field;
}
#Override
public Object invoke(Object target, Object[] args) throws IllegalAccessException {
try {
return field.get(target);
} catch (IllegalAccessException e) {
if (Reflector.canControlMemberAccessible()) {
field.setAccessible(true);
return field.get(target);
} else {
throw e;
}
}
}
#Override
public Class<?> getType() {
return field.getType();
}
}
the intercepor of mine:
#Intercepts({
#Signature(
type = StatementHandler.class,
method = "prepare",
args = {Connection.class, Integer.class})
})
public class SqlIdInterceptor implements Interceptor {
private static final int MAX_LEN = 256;
private final RoomboxLogger logger = RoomboxLogManager.getLogger();
#Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = realTarget(invocation.getTarget());
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
String originalSql = boundSql.getSql();
MappedStatement mappedStatement =
(MappedStatement) metaObject.getValue("delegate.mappedStatement");
String id = mappedStatement.getId();
if (id != null) {
int len = id.length();
if (len > MAX_LEN) {
logger.warn("too long id", "id", id, "len", len);
}
}
String newSQL = "# " + id + "\n" + originalSql;
metaObject.setValue("delegate.boundSql.sql", newSQL);
return invocation.proceed();
}
#SuppressWarnings("unchecked")
public static <T> T realTarget(Object target) {
if (Proxy.isProxyClass(target.getClass())) {
MetaObject metaObject = SystemMetaObject.forObject(target);
return realTarget(metaObject.getValue("h.target"));
}
return (T) target;
}
}
Flame Graph
enter image description here
enter image description here
I need help, how to avoid throw exceptions, is any other way to reslove this problem?
thanks.

Tree like view of Triplets and remove URI's

I have written a code in java that reads the ontology and print the triplets. the code is working fine. i want to hide the URI's in output and also print the output in the tree hierarchy form. Currently it gives me output in lines. Any idea how can i do this.
Tree Form Like:
Thing
Class
SubClass
Individual
so on ...
this is the ReadOntology class, this class i use in servlet.
public class ReadOntology {
public static OntModel model;
public static void run(String ontologyInFile) {
model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, null);
InputStream ontologyIn = FileManager.get().open(ontologyInFile);
loadModel(model, ontologyIn);
}
protected static void loadModel(OntModel m, InputStream ontologyIn) {
try {
m.read(ontologyIn, "RDF/XML");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
this is the servlet
public class Ontology extends HttpServlet{
OntClass ontClass = null;
public void service(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException
{
PrintWriter out = res.getWriter();
ServletContext context = this.getServletContext();
String fullPath = context.getRealPath("/WEB-INF/Data/taxi.owl");
ReadOntology.run(fullPath);
SimpleSelector selector = new SimpleSelector(null, null, (RDFNode)null);
StmtIterator iter = ReadOntology.model.listStatements(selector);
while(iter.hasNext()) {
Statement stmt = iter.nextStatement();
out.print(stmt.getSubject().toString());
out.print(stmt.getPredicate().toString());
out.println(stmt.getObject().toString());
}
}
}
As one step towards your goal, this groups the statements by subject, and for the predicates only shows the local name:
ResIterator resIt = ReadOntology.model.listSubjects()
while (resIt.hasNext()) {
Resource r = resIt.nextResource();
out.println(r);
StmtIterator iter = r.listProperties();
while (iter.hasNext()) {
Statement stmt = iter.nextStatement();
out.print(" ");
out.print(stmt.getPredicate().getLocalName());
out.println(stmt.getObject());
}
}
There are lots of useful methods in the API for Resource and Model.
To render a full class tree, use the methods on OntModel and OntClass. Perhaps:
private void printClass(Writer out, OntClass clazz, int indentation) {
String space = ' '.repeat(indentation);
// print space + clazz.getLocalName()
...
// iterate over clazz.listSubClasses(true)
// and call printClass for each with indentation increased by 1
...
// iterator over clazz.listInstances()
// and print all their properties as in the
// snippet above but with space added
}
Then in the service method, iterate over the OntModel's classes, and for any where hasSuperClass() is false, call printClass(out, clazz, 0).

Getting NullPointerException with AndroidAnnotations & ORMLite

I am using AndroidAnnotations and SQLite with ORMLite and am trying to get the database up and running. I was able to create the table and make a test-insert of a Contact object a few days ago.
However, I did some changes and then it stopped working - unfortunately I was not able to revert my changes and now I'm stuck and can't get it working anymore.
Whenever I start the app I get this error:
02-12 23:09:39.931 11766-11766/net.gazeapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: net.gazeapp, PID: 11766
java.lang.RuntimeException: Unable to start activity ComponentInfo{net.gazeapp/net.gazeapp.MainActivity_}: java.lang.NullPointerException: Attempt to invoke virtual method 'int net.gazeapp.data.ContactDao.create(java.lang.Object)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int net.gazeapp.data.ContactDao.create(java.lang.Object)' on a null object reference
at net.gazeapp.service.ContactService.addContact(ContactService.java:55)
at net.gazeapp.MainActivity.testNewORM(MainActivity.java:171)
at net.gazeapp.MainActivity.createView(MainActivity.java:148)
at net.gazeapp.MainActivity_.onViewChanged(MainActivity_.java:111)
at org.androidannotations.api.view.OnViewChangedNotifier.notifyViewChanged(OnViewChangedNotifier.java:41)
at net.gazeapp.MainActivity_.setContentView(MainActivity_.java:57)
at net.gazeapp.MainActivity_.onCreate(MainActivity_.java:45)
at android.app.Activity.performCreate(Activity.java:6251)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
at android.app.ActivityThread.-wrap11(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
So here is my MainActivity in which I do the ORM-testing (in the testNewORM() method):
#EActivity(R.layout.activity_main_viewpagertab)
#OptionsMenu(R.menu.menu_main)
public class MainActivity extends BaseActivity implements ObservableScrollViewCallbacks {
private final String TAG = getClass().getSimpleName();
private int mBaseTranslationY;
private NavigationAdapter mPagerAdapter;
private Contact mContact;
private static String[] tabTitles = null;
#App
GazeApplication application;
#ViewById(R.id.header)
View mHeaderView;
#ViewById(R.id.toolbar)
View mToolbarView;
#ViewById(R.id.pager)
ViewPager mPager;
#ViewById(R.id.fab)
FloatingActionButton fab;
#ViewById(R.id.adview)
MoPubView mAdView;
#Bean
ContactService contactService;
#AfterViews
void createView() {
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
Tools.readJsonFile(this, "fetishes.json");
// TAB TITLES: RECENT, ALL, MY MEDIA
tabTitles = new String[]{getString(R.string.recent), getString(R.string.all), getString(R.string.my_media)};
ViewCompat.setElevation(mHeaderView, getResources().getDimension(R.dimen.toolbar_elevation));
mPagerAdapter = new NavigationAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
SlidingTabLayout slidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
slidingTabLayout.setCustomTabView(R.layout.tab_indicator, android.R.id.text1);
slidingTabLayout.setSelectedIndicatorColors(getResources().getColor(R.color.colorAccent));
slidingTabLayout.setDistributeEvenly(true);
slidingTabLayout.setViewPager(mPager);
// When the page is selected, other fragments' scrollY should be adjusted
// according to the toolbar status(shown/hidden)
slidingTabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i2) {
}
#Override
public void onPageSelected(int i) {
propagateToolbarState(toolbarIsShown());
}
#Override
public void onPageScrollStateChanged(int i) {
}
});
propagateToolbarState(toolbarIsShown());
displayAdBanner();
// TESTING ORMAPPER
// TESTING ORMAPPER
testNewORM();
}
void testNewORM() {
java.util.Date date = new java.util.Date();
Timestamp timeNow = new Timestamp(date.getTime());
Timestamp birthdateTimestamp = new Timestamp(date.getTime());
Date birthdate = new Date();
try {
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
birthdate = dateFormat.parse("04/07/1980");
long time = birthdate.getTime();
birthdateTimestamp = new Timestamp(time);
} catch (ParseException e) {
e.printStackTrace();
}
Contact contact = new Contact("Dominik Erbsland");
contact.setBirthdate(birthdate);
try {
mContact = contactService.addContact(contact);
} catch (ItemNotFoundException | SQLException e) {
Log.e(TAG, e.getLocalizedMessage());
e.printStackTrace();
}
}
...
}
And here the other used classes:
#EBean(scope = EBean.Scope.Singleton)
public class ContactService {
private static final String TAG = ContactService.class.getSimpleName();
#RootContext
Context ctx;
#OrmLiteDao(helper = DatabaseHelper.class)
ContactDao mContactDao;
public Contact getContact(int contactId) throws ItemNotFoundException, SQLException {
Contact contact = mContactDao.queryForId(contactId);
if (contact == null) {
Log.e(TAG, "Contact not found in database");
throw new ItemNotFoundException();
}
return contact;
}
public List<Contact> getContacts() throws ItemNotFoundException, SQLException {
List<Contact> contact = mContactDao.queryForAll();
if (contact == null) {
Log.e(TAG, "Contacts not found in database");
throw new ItemNotFoundException();
}
return contact;
}
public Contact addContact(Contact contact) throws SQLException {
int rowsAffected = 0;
try {
rowsAffected = mContactDao.create(contact);
} catch (SQLException e) {
Log.e(TAG, e.getLocalizedMessage());
e.printStackTrace();
}
Log.d(TAG, "New Contact ID: " + contact.getId());
return contact;
}
public void testOutput() {
Log.d(TAG, "THIS IS A TEST OUTPUT");
}
}
here my database helper:
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
private static final String DATABASE_NAME = "Gaze.db";
private static final int DATABASE_VERSION = 1;
private final Context context;
// the DAO object we use to access the Person table
private Dao<Contact, Integer> contactDao = null;
private Dao<MyPreferences, Integer> preferencesDao = null;
private Dao<SecurityQuestion, Integer> securityQuestionDao = null;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
/**
* This is called when the database is first created. Usually you should call createTable statements here to create
* the tables that will store your data.
*/
#Override
public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) {
try {
Log.i(DatabaseHelper.class.getName(), "onCreate");
TableUtils.createTable(connectionSource, Contact.class);
} catch (SQLException e) {
Log.e(DatabaseHelper.class.getName(), "Can't create database", e);
throw new RuntimeException(e);
}
}
/**
* This is called when your application is upgraded and it has a higher version number. This allows you to adjust
* the various data to match the new version number.
*/
#Override
public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
try {
Log.i(DatabaseHelper.class.getName(), "onUpgrade");
TableUtils.dropTable(connectionSource, Contact.class, true);
// after we drop the old databases, we create the new ones
onCreate(db, connectionSource);
} catch (SQLException e) {
Log.e(DatabaseHelper.class.getName(), "Can't drop databases", e);
throw new RuntimeException(e);
}
}
/**
* Returns the Database Access Object (DAO) for our Person class. It will create it or just give the cached
* value.
*/
public Dao<Contact, Integer> getContactDao() throws SQLException {
if (contactDao == null) {
contactDao = getDao(Contact.class);
}
return contactDao;
}
public Dao<MyPreferences, Integer> getPreferencesDao() throws SQLException {
if (preferencesDao == null) {
preferencesDao = getDao(MyPreferences.class);
}
return preferencesDao;
}
public Dao<SecurityQuestion, Integer> getSecurityQuestionDao() throws SQLException {
if (securityQuestionDao == null) {
securityQuestionDao = getDao(SecurityQuestion.class);
}
return securityQuestionDao;
}
/**
* Close the database connections and clear any cached DAOs.
*/
#Override
public void close() {
super.close();
contactDao = null;
preferencesDao = null;
securityQuestionDao = null;
}
}
and the data class:
#DatabaseTable(tableName = "Contact", daoClass = ContactDao.class)
public class Contact implements Serializable {
#DatabaseField(generatedId = true, columnName = PersistentObject.ID)
int id;
#DatabaseField(index = true)
String contactName;
#DatabaseField
String mainPic;
#DatabaseField(dataType = DataType.DATE_STRING, format = "yyyy-MM-dd HH:mm:ss.S")
Date birthdate;
#DatabaseField
boolean knowPersonally;
#DatabaseField(dataType = DataType.DATE_STRING, format = "yyyy-MM-dd HH:mm:ss.S")
Timestamp created;
#DatabaseField(dataType = DataType.DATE_STRING, format = "yyyy-MM-dd HH:mm:ss.S")
Timestamp lastMod;
public Contact() {
// needed by ormlite
}
...
}
and the ContactDao:
public class ContactDao extends BaseDaoImpl<Contact, Integer> {
public ContactDao(Class<Contact> dataClass) throws SQLException {
super(dataClass);
}
public ContactDao(ConnectionSource connectionSource, Class<Contact> dataClass) throws SQLException {
super(connectionSource, dataClass);
}
public ContactDao(ConnectionSource connectionSource, DatabaseTableConfig<Contact> tableConfig) throws SQLException {
super(connectionSource, tableConfig);
}
public List<Contact> getContacts() throws SQLException {
return queryForAll();
}
}
So in the ContactService class at "mContactDao.create(contact);" it crashed with the Exception. This is the part I don't understand because ContactService is annotated with #EBean and is being accessed in MainActivity with "#Bean
ContactService contactService;" and shouldn't be null there...
Thanks for any help or hints in advance.
The problem is the following:
The code is trying to access the mContactDao field, but it is indeed null, altough it should be injected by AndroidAnnotations. But the field cannot be injected, because the dao creation fails with an exception. This is logged by AndroidAnnotations, you can check it in LogCat.
The cause of the problem lies in the Contact class. You are using List<Something> fields, but ORMLite does not know how to persist the java.util.List object. You can either use a custom persister, or you can use foreign fields:
Contact.java:
#ForeignCollectionField
private ForeignCollection<Address> adresses;
Update:
Applying the ForestCollectionField changes and debugging again showed another problem. The DataType.DATE_STRING persister cannot be used with the java.sql.Timestamp class. But you can use DataType.TIME_STAMP instead:
#DatabaseField(dataType = DataType.TIME_STAMP, format = "yyyy-MM-dd HH:mm:ss.S")
Timestamp created;
#DatabaseField(dataType = DataType.TIME_STAMP, format = "yyyy-MM-dd HH:mm:ss.S")
Timestamp lastMod;

spring data mongodb converter

I am using spring data mongo-db 1.4.1.RELEASE.
My entity 'Event' has a getter method which is calculated based on other properties:
public int getStatus() {
return (getMainEventId() == null) ? (elapseTimeInMin() < MINIMUM_TIME ? CANDIDATE :
VALID) : POINTER;
}
I wanted the property 'status' to be persisted only through the getter ,so I wrote converters:
#WritingConverter
public class EventWriteConverter implements Converter<Event ,BasicDBObject > {
static final Logger logger = LoggerFactory.getLogger(EventWriteConverter.class.getCanonicalName());
public BasicDBObject convert(Event event) {
logger.info("converting " +event );
if (event.getMainEventId() != null)
return new BasicDBObject("mainEventId", event.getMainEventId() );
BasicDBObject doc = new BasicDBObject("status",event.getStatus()).
append("updated_date",new Date()).
append("start",event.getS0()).
append("end",event.getS1()).
append("location",event.getLocation()).
;
BasicDBList list = new BasicDBList();
doc.append("access_points",event.getHotPoints());
return doc;
}
#ReadingConverter
public class EventReadConverter implements Converter<BasicDBObject, Event> {
#Inject
HotPointRepositry hotRepositry;
static final Logger logger = LoggerFactory.getLogger(EventReadConverter.class.getCanonicalName());
public Event convert(BasicDBObject doc) {
logger.info(" converting ");
Event event = new Event();
event.setId(doc.getObjectId("_id"));
event.setS0(doc.getDate("start"));
event.setS1(doc.getDate("end"));
BasicDBList dblist = (BasicDBList) doc.get("hot_points");
if (dblist != null) {
for (Object obj : dblist) {
ObjectId hotspotId = ((BasicDBObject) obj).getObjectId("_id");
event.addHot(hotRepositry.findOne(hotId));
}
}
dblist = (BasicDBList) doc.get("devices");
if (dblist != null) {
for (Object obj : dblist)
event.addDevice(obj.toString());
}
event.setMainEventId(doc.getObjectId("mainEventId"));
return event;
}
}
My test mongo configuration is
#Profile("test")
#Configuration
#EnableMongoRepositories(basePackages = "com.echo.spring.data.mongo")
#ComponentScan(basePackages = "com.echo.spring.data.mongo" )
public class MongoDbTestConfig extends AbstractMongoConfiguration {
static final Logger logger = LoggerFactory.getLogger(MongoDbTestConfig.class.getCanonicalName());
#Override
protected String getDatabaseName() {
return "echo";
}
#Override
public Mongo mongo() {
return new Fongo("echo-test").getMongo();
}
#Override
protected String getMappingBasePackage() {
return "com.echo.spring.data.mongo";
}
#Bean
#Override
public CustomConversions customConversions() {
logger.info("loading custom converters");
List<Converter<?, ?>> converterList = new ArrayList<Converter<?, ?>>();
converterList.add(new EventReadConverter());
converterList.add(new EventWriteConverter());
CustomConversions cus = new CustomConversions(converterList);
return new CustomConversions(converterList);
}
}
And my test (using fongo) is
ActiveProfiles("test")
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = MongoDbTestConfig.class )
public class SampleMongoApplicationTests {
#Test
#ShouldMatchDataSet(location = "/MongoJsonData/events.json")
public void shouldSaveEvent() throws IOException {
URL url = Resources.getResource("MongoJsonData/events.json");
List<String> lines = Resources.readLines(url,Charsets.UTF_8);
for (String line : lines) {
Event event = objectMapper.readValue(line.getBytes(),Event.class);
eventRepository.save(event);
}
}
I can see the converters are loaded when the configuration customConversions() is called
I added logging and breakpoints in the convert methods but they do not seems to be
called when I run or debug, though they are loaded .
What am I doing wrong ?
I had a similar situation, I followed Spring -Mongodb storing/retrieving enums as int not string
and I need both the converter AND converterFactory wired to get it working.

EntityFramework 6.0.0-alpha3 - EdmxWriter.WriteEdmx() fails after update to alpha3 from alpha2

The following extension works for EF6 alpha2 but stopped working with alpha3 with null reference exception. The failing statement is the EdmxWriter.WriteEdmx(..)
The views pre-generation is performed on a code-first context.
How to achieve pre-generate views using EF6 alpha3?
public static PreGeneratedViews PreGenerateViews<T>(this T dbContext) where T : DbContext
{
Trace.TraceInformation("PreGenerating views");
//define ef collections
EdmItemCollection edmItemCollection = null;
StoreItemCollection storeItemCollection = null;
StorageMappingItemCollection mappingItemCollection = null;
//get ef collections
GetItemCollections(
GetEdmx(dbContext),
out edmItemCollection,
out storeItemCollection,
out mappingItemCollection);
IList<EdmSchemaError> errors = null;
//get the generated views
Dictionary<string, string> extentViews = GetExtentViews(mappingItemCollection, out errors);
//return the pregenerated views as string (xml document)
return new PreGeneratedViews
{
EdmEntityContainerName = edmItemCollection.GetItems<EntityContainer>().Single().Name,
StoreEntityContainerName = storeItemCollection.GetItems<EntityContainer>().Single().Name,
HashOverMappingClosure =
ReflectionHelper.GetMappingClosureHash(edmItemCollection.EdmVersion,
mappingItemCollection),
HashOverAllExtentViews =
ReflectionHelper.GenerateHashForAllExtentViewsContent(edmItemCollection.EdmVersion,
extentViews),
ViewCount = extentViews.Count,
Views = CreateViews(extentViews),
ViewsEmbeddedResourceName =
string.Format("DbContextViews{0}.xml", Guid.NewGuid().ToString("N")),
};
}
private static XDocument GetEdmx(DbContext dbContext)
{
var ms = new MemoryStream();
using (XmlWriter writer = XmlWriter.Create(ms))
{
EdmxWriter.WriteEdmx(dbContext, writer);
}
ms.Position = 0;
return XDocument.Load(ms);
}
private static void SplitEdmx(XDocument edmx, out XmlReader csdlReader, out XmlReader ssdlReader,
out XmlReader mslReader)
{
// xml namespace agnostic to make it work with any version of Entity Framework
XNamespace edmxNs = edmx.Root.Name.Namespace;
XElement storageModels = edmx.Descendants(edmxNs + "StorageModels").Single();
XElement conceptualModels = edmx.Descendants(edmxNs + "ConceptualModels").Single();
XElement mappings = edmx.Descendants(edmxNs + "Mappings").Single();
ssdlReader = storageModels.Elements().Single(e => e.Name.LocalName == "Schema").CreateReader();
csdlReader = conceptualModels.Elements().Single(e => e.Name.LocalName == "Schema").CreateReader();
mslReader = mappings.Elements().Single(e => e.Name.LocalName == "Mapping").CreateReader();
}
private static void GetItemCollections(XDocument edmx, out EdmItemCollection edmItemCollection,
out StoreItemCollection storeItemCollection,
out StorageMappingItemCollection mappingItemCollection)
{
// extract csdl, ssdl and msl artifacts from the Edmx
XmlReader csdlReader, ssdlReader, mslReader;
SplitEdmx(edmx, out csdlReader, out ssdlReader, out mslReader);
// Initialize item collections
edmItemCollection = new EdmItemCollection(new[] {csdlReader});
storeItemCollection = new StoreItemCollection(new[] {ssdlReader});
mappingItemCollection = new StorageMappingItemCollection(edmItemCollection, storeItemCollection,
new[] {mslReader});
}
private static Dictionary<string, string> GetExtentViews(StorageMappingItemCollection mappingItemCollection,
out IList<EdmSchemaError> errors)
{
Dictionary<EntitySetBase, string> views = ReflectionHelper.GenerateViews(mappingItemCollection, out errors);
if (errors != null && errors.Any())
{
return null;
}
var extentViews = new Dictionary<string, string>(views.Count);
foreach (var kvp in views)
{
extentViews.Add(
GetExtentFullName(kvp.Key),
kvp.Value.Replace("\r\n", "\n")); // replace accounts for Xml new line normalization
}
return extentViews;
}
private static string GetExtentFullName(EntitySetBase entitySet)
{
return string.Format("{0}.{1}", entitySet.EntityContainer.Name, entitySet.Name);
}
private static string CreateViews(Dictionary<string, string> extentViews)
{
var sb = new StringBuilder();
//var embeddedViewsFileName = Path.ChangeExtension(Host.TemplateFile, "xml");
using (XmlWriter writer = XmlWriter.Create(sb, new XmlWriterSettings
{
Indent = true,
Encoding = Encoding.UTF8
}))
{
writer.WriteStartElement("views");
foreach (var kvp in extentViews)
{
writer.WriteStartElement("view");
writer.WriteAttributeString("extent", kvp.Key);
writer.WriteCData(kvp.Value);
writer.WriteEndElement();
}
writer.WriteEndElement();
}
return sb.ToString();
}
#region Nested type: ReflectionHelper
private static class ReflectionHelper
{
private static readonly Assembly efAssembly = typeof (StorageMappingItemCollection).Assembly;
private static readonly MethodInfo generateViewsMethodInfo =
typeof (StorageMappingItemCollection).GetMethod("GenerateEntitySetViews",
BindingFlags.NonPublic | BindingFlags.Instance);
private static readonly MethodInfo getMappingClosureHashMethodInfo =
efAssembly.GetType("System.Data.Entity.Core.Mapping.MetadataMappingHasherVisitor", true)
.GetMethod("GetMappingClosureHash", BindingFlags.Static | BindingFlags.NonPublic);
private static readonly MethodInfo generateHashForAllExtentViewsContentMethodInfo =
efAssembly.GetType("System.Data.Entity.Core.Common.Utils.MetadataHelper", true)
.GetMethod("GenerateHashForAllExtentViewsContent", BindingFlags.Static | BindingFlags.NonPublic);
public static Dictionary<EntitySetBase, string> GenerateViews(
StorageMappingItemCollection mappingItemCollection, out IList<EdmSchemaError> errors)
{
errors = null;
return
(Dictionary<EntitySetBase, string>)
generateViewsMethodInfo.Invoke(mappingItemCollection, new object[] {errors});
}
public static string GetMappingClosureHash(double schemaVersion,
StorageMappingItemCollection mappingItemCollection)
{
return (string) getMappingClosureHashMethodInfo.Invoke(
null,
new object[]
{
schemaVersion,
// CodeFirst currently creates always one entity container
mappingItemCollection.GetItems<GlobalItem>().Single(
i => i.GetType().Name == "StorageEntityContainerMapping")
});
}
public static string GenerateHashForAllExtentViewsContent(double schemaVersion,
Dictionary<string, string> extentViews)
{
return (string) generateHashForAllExtentViewsContentMethodInfo.Invoke(
null,
new object[] {schemaVersion, extentViews});
}
}
The stacktrace is the following:
NullReferenceException
at: System.Data.Entity.Edm.Serialization.EdmSerializationVisitor.VisitEdmAssociationSet(AssociationSet item)
at: System.Data.Entity.Edm.EdmModelVisitor.VisitCollection[T](IEnumerable1 collection, Action1 visitMethod)
at: System.Data.Entity.Edm.EdmModelVisitor.VisitAssociationSets(EntityContainer container, IEnumerable`1 associationSets)
at: System.Data.Entity.Edm.EdmModelVisitor.VisitEdmEntityContainer(EntityContainer item)
at: System.Data.Entity.Edm.Serialization.EdmSerializationVisitor.VisitEdmEntityContainer(EntityContainer item)
at: System.Data.Entity.Edm.EdmModelVisitor.VisitCollection[T](IEnumerable1 collection, Action1 visitMethod)
at: System.Data.Entity.Edm.EdmModelVisitor.VisitEntityContainers(IEnumerable`1 entityContainers)
at: System.Data.Entity.Edm.EdmModelVisitor.VisitEdmModel(EdmModel item)
at: System.Data.Entity.Edm.Serialization.EdmSerializationVisitor.Visit(EdmModel edmModel, String namespaceName, String provider, String providerManifestToken)
at: System.Data.Entity.Edm.Serialization.EdmSerializationVisitor.Visit(EdmModel edmModel, String provider, String providerManifestToken)
at: System.Data.Entity.Edm.Serialization.SsdlSerializer.Serialize(EdmModel dbDatabase, String provider, String providerManifestToken, XmlWriter xmlWriter, Boolean serializeDefaultNullability)
at: System.Data.Entity.ModelConfiguration.Edm.Serialization.EdmxSerializer.WriteEdmxRuntime()
at: System.Data.Entity.ModelConfiguration.Edm.Serialization.EdmxSerializer.Serialize(DbDatabaseMapping databaseMapping, DbProviderInfo providerInfo, XmlWriter xmlWriter)
at: System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbModel model, XmlWriter writer)
at: System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbContext context, XmlWriter writer)
at: **.DbContextPreGenerateViewExtension.GetEdmx(DbContext dbContext)
Thanks!
I just submitted a fix for work item 867 (35852e8392ad). It should fix the NRE. The fix should be included in the today's nightly build. Can you give it a try and let me know if this fixed the problem?
This is a known bug in Alpha 3.