Breeze odata and collections - collections

I am trying to fetch metadata from odata server, in which one of the entities has
<Property Name="StakeHoldersLGIds" Type="Collection(Edm.Int32)" Nullable="false"/>
<Property Name="CollaboratorsLGIds" Type="Collection(Edm.Int32)" Nullable="false"/>
it failes to parse the metadata. I saw that in the parsing Breeze treats it as simpleItems cause there is the . and the parsing returns array of 2.
var typeParts = csdlProperty.type.split(".");
if (typeParts.length === 2) {
dp = parseCsdlSimpleProperty(parentType, csdlProperty, keyNamesOnServer);
and this looks like a bug, is there a work around?

Related

Index error on querying google datastore using gcloud

I am trying to use google datastore for my non GAE application.
For that i have created kinds and ancestor related entities in datastore using gcloud python library.
Also updated datastore index configuration for all the kinds using gcd tool via WEB-INF/datastore-indexes.xml file and its status' are serving.
However i can not successfully query the index based columns either in console or using gcloud lib.
Here is the query & traceback
from gcloud import datastore
ds = datastore.Client(dataset_id='XXXXXX')
query = datastore.Query(ds, kind='event')
query.add_filter('EvtName', '=', 'buy')
query.add_filter('EventDateTime', '<=', datetime.datetime(2015, 10, 22, 8, 45))
for itm in query.fetch():
print(dict(itm))
gcloud.exceptions.PreconditionFailed: 412 no matching index found.
here is my datastore-indexes.xml config
<?xml version="1.0" encoding="utf-8"?>
<datastore-indexes
autoGenerate="false">
<datastore-index kind="event" ancestor="true">
<property name="EvtName" direction="desc" />
<property name="EventDateTime" direction="desc" />
</datastore-index>
<datastore-index kind="att" ancestor="true">
<property name="EvtAttName" direction="desc" />
<property name="EventDateTime" direction="desc" />
</datastore-index>
<datastore-index kind="att_val" ancestor="true">
<property name="AttValue" direction="desc" />
<property name="EventDateTime" direction="desc" />
</datastore-index>
<datastore-index kind="user" ancestor="true">
<property name="EventDateTime" direction="desc" />
</datastore-index>
</datastore-indexes>
am i missing something?
All of your indexes are designed to be used with ancestor queries (note the ancestor=true). However, your actual query does not query within a specific ancestor.
In order to answer your specific query, you need the index:
<datastore-index kind="event" ancestor="false">
<property name="EvtName" direction="desc" />
<property name="EventDateTime" direction="desc" />
</datastore-index>
Or, if you actually do want to query for entities with a specific parent, make sure to add an ancestor filter with Query#hasAncestor(Key parentKey).

Debug spring mvc view rendering time

I am currently using Spring MVC 3.x,
and using the freemarker view resolver.
Recently i have been wondering about the execution time that it takes for a view to translate into html before getting sent back as a response. I would like to do tunings if things are slow in this area, which is why i need some numbers.
In plain freemarker mode, i can actually do the simple System.currentTimeMillis() between these to find out the execution time :
long start = System.currentTimeMillis();
// this could be slow or fast depending on the caching used
Template temp = cfg.getTemplate(ftlName);
...
temp.process(model, myWriter); // depends on the writer
System.out.printf("done in %s ms", System.currentTimeMillis() - start);
But how do i do this when with spring mvc's freemaker view rendering ?
You might consider extending org.springframework.web.servlet.view.freemarker.FreeMarkerView and configuring FreeMarkerViewResolver with your custom logging view implementation.
Logging view implementation could look like this:
public class LoggingFreeMarkerView extends FreeMarkerView {
private static final transient Log log = LogFactory.getLog(LoggingFreeMarkerView.class);
#Override
protected void doRender(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
long start = System.currentTimeMillis();
super.doRender(model, request, response);
log.debug("Freemarker rendered " + request.getRequestURI() + " in " + (System.currentTimeMillis() - start) + " ms");
}
}
And wire the view resolver with new class:
<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver" autowire="no">
<property name="viewClass" value="com.example.LoggingFreeMarkerView" />
<property name="cache" value="false" /> <!-- cache disabled for performance monitoring -->
<property name="prefix" value="" />
<property name="suffix" value=".ftl" />
<property name="contentType" value="text/html;charset=utf-8" />
<property name="exposeRequestAttributes" value="true" />
<property name="requestContextAttribute" value="base" />
</bean>
You are going to calculate just on server side merging template with data,Main problem is when freemarker executing on page ,As you know freemarker built on top of jsp page so you should bring code to jsp side to calculate execution time,
As my experience according to data size load time in freemarker is different.
if else condition also is too slow compare to jstl!
I can recommend thymeleaf for spring that allowing templates to be working prototypes on not xml style .

Spring MVC JDBC DataSourceTransactionManager: Data committed even after readonly=true

I am currently developing a Spring MVC application.I have configured a JDBC TransactionManager and I am doing declarative transaction management using AOP XML.However, even if I configure the method to run on a read-only=true, it still commits the transaction.
Database : Oracle 10g
My database-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schem...ring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<property name="defaultAutoCommit" value="false" />
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:com/mybatis/mappers/*.xml" />
</bean>
<!--
the transactional advice (what 'happens'; see the <aop:advisor/> bean
below)
-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- the transactional semantics... -->
<tx:attributes>
<!-- all methods starting with 'get' are read-only -->
<tx:method name="get*" read-only="true" />
<!-- other methods use the default transaction settings (see below) -->
<tx:method name="*" read-only="true" rollback-for="RuntimeException"/>
</tx:attributes>
</tx:advice>
<!--
ensure that the above transactional advice runs for any execution of
an operation defined by the FooService interface
-->
<aop:config>
<aop:pointcut id="fooServiceOperation"
expression="execution(* com.service.EmployeeService.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation" />
</aop:config>
</beans>
My controller
package com.service;
import java.util.List;
import com.mybatis.dao.EmployeeMapperInterface;
import com.spring.model.Employee;
public class EmployeeService implements EmployeeBaseService{
EmployeeMapperInterface employeeMapper;
public EmployeeMapperInterface getEmployeeMapper() {
return employeeMapper;
}
public void setEmployeeMapper(EmployeeMapperInterface employeeMapper) {
this.employeeMapper = employeeMapper;
}
#Override
public Employee getEmployeeById(long empId){
//retrieve from database
List empList = employeeMapper.getEmployeeWithId(empId);
if(empList != null && empList.size()>0){
return (Employee) empList.get(0);
}
return null;
}
#Override
public long saveEmployee(Employee employee){
long empId = 0l;
if(employee.getEmpId()==0){
empId = new Long( employeeMapper.insertEmployee(employee));
}else{
employeeMapper.updateEmployee(employee);
empId = employee.getEmpId();
}
try {
System.out.println("gonna sleep");
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return empId;
}
How do I prevent the auto commit?I have also noticed that even if I don't put any transaction management code, the code still commits. Note, the transaction advice is however,invoked as when I put a no-rollback-for for RuntimeException and then do a 1/0, it correctly commits the data and rolls back if I put the same as rollback-for.
I have also tried out the query timeout by putting the thread on sleep, even that doesn't work, but I figure that timeout might be for an actual query, so thats fine.
Thanks in advance!
The advice read-only is only advice. It is not a requirement that the underlying transaction management system prevent writes when something is marked read-only, it is meant more as an optimization hint, saying that this method is read only, so you don't need to worry about it changing things. Some transaction managers will complain if changes are made in a read-only transaction, some will not. Generally, datasources acquired via JNDI will not. In any case, you should not rely on read-only advice preventing changes from being written back to disk.
Your options for preventing changes from being persisted are:
Mark the transaction rollback only or throw an exception having the same effect
Detach/evict the object from the transaction session before you change it
Clone the object and use the clone
DataSourceTransactionManager begins transaction with doBegin method.
From this method DataSourceUtils.prepareConnectionForTransaction called.
Inside this method you can see following code block:
if (definition != null && definition.isReadOnly()) {
try {
if (logger.isDebugEnabled()) {
logger.debug("Setting JDBC Connection [" + con + "] read-only");
}
con.setReadOnly(true);
}
catch (SQLException ex) {
So you could configure your logging framework to set log-level to DEBUG for DataSourceUtils class.
Or you could set breakpoint in this place and debug manually.
According to this article I expect that SET TRANSACTION READ ONLY will be executed on your Oracle connection.
And from Oracle docs we could see benefits which you receive in case of success:
By default, the consistency model for Oracle guarantees statement-level read consistency, but does not guarantee transaction-level read consistency (repeatable reads). If you want transaction-level read consistency, and if your transaction does not require updates, then you can specify a read-only transaction. After indicating that your transaction is read-only, you can execute as many queries as you like against any database table, knowing that the results of each query in the read-only transaction are consistent with respect to a single point in time.
The read-only behaviour is strictly driver specific. Oracle driver ignores this flag entirely. For instance the same update statements executed in Oracle will modify the database if run in read-only transaction, while in HSQL2 I was getting db level exceptions.
I know no other way than explicit rollback through api or exception to prevent commit in Oracle. Also this way your code will be portable between different drivers and databases.
The answer is on Spring MVC Mybatis transaction commit
Detailed stack traces are also available.
To summarize,
Read-only is only an advice and it guarantees nothing, and I would
really like the Spring docs to be updated about this.
whenever a query is executed in Oracle using Mybatis, it is in the context of a transaction which is automatically started,
committed(or rolled back, if execption is raised),and closed by
Mybatis.
Logging the application was a good idea and it helped me to find out how the actual transactions are started etc
.

Unauthorized error in Plone test, though content type can be added through the web

I've got a content type based on ATFolder:
ConceptSheetFolderSchema = folder.ATFolderSchema.copy()
ConceptSheetFolderSchema['title'].widget.label = _(u"Title")
ConceptSheetFolderSchema['title'].widget.description = _(u"")
ConceptSheetFolderSchema['title'].storage = atapi.AnnotationStorage()
ConceptSheetFolderSchema['description'].widget.label = _(u"Description")
ConceptSheetFolderSchema['description'].widget.description = _("")
ConceptSheetFolderSchema['description'].storage = atapi.AnnotationStorage()
finalizeATCTSchema(ConceptSheetFolderSchema, folderish=True, moveDiscussion=False)
class ConceptSheetFolder(folder.ATFolder):
"""
This is the central container for concept sheets in the site
"""
implements(IConceptSheetFolder)
portal_type = "Concept Sheet Folder"
_at_rename_after_creation = True
schema = ConceptSheetFolderSchema
title = atapi.ATFieldProperty('title')
description = atapi.ATFieldProperty('description')
atapi.registerType(ConceptSheetFolder, PROJECTNAME)
I can add a ConceptSheetFolder no problem through the Plone interface, but I can't get this basic test to work:
class TestContent(unittest.TestCase):
layer = PROJECT_CONCEPTSHEETS_INTEGRATION_TESTING
def test_hierarchy(self):
portal = self.layer['portal']
# Ensure that we can create the various content types without error
setRoles(portal, TEST_USER_ID, ('Manager',))
portal.invokeFactory('Concept Sheet Folder', 'csf1', title=u"Concept Sheet folder")
portal['csf1'].invokeFactory('project.ConceptSheet', 'cs1', title=u"ConceptSheet")
portal['csf1']['cs1'].invokeFactory('project.ConceptMilestone', 'cs1', title=u"Approved")`
I get a error
Unauthorized: Cannot create Concept Sheet Folder when I try this test. I Googled around a bit and found this Nabble post, leading me to look at isConstructionAllowed() in Plone/CMFCore/TestTools.py. Using pdb, I found that ._queryFactoryMethod(), when run in this context, is returning 'None'.
So it appears the FactoryTool for this type isn't working, at least not in the test. I've got the test in the normal GenericSetup place (types.xml, Concept_Sheet_Folder.xml, factorytool.xml), and I'm at a lost as to what else could be causing this problem. Any ideas?
Bonus question: why does this work in the Plone interface but not in the test?
Edit (Dec 13, 2011): Here's my Concept_Sheet_Folder.xml
<?xml version="1.0"?>
<object name="Concept Sheet Folder"
meta_type="Factory-based Type Information with dynamic views"
i18n:domain="iedea.conceptsheets" xmlns:i18n="http://xml.zope.org/namespaces/i18n">
<property name="title" i18n:translate="">Concept Sheet Folder</property>
<property name="description"
i18n:translate="">A folder which can contain concept sheets.</property>
<property name="content_icon">++resource++conceptsheetfolder_icon.gif</property>
<property name="content_meta_type">Concept Sheet Folder</property>
<property name="product">iedea.conceptsheets</property>
<property name="factory">addConceptSheetFolder</property>
<property name="immediate_view">atct_edit</property>
<property name="global_allow">True</property>
<property name="filter_content_types">True</property>
<property name="allowed_content_types">
<element value="Concept Sheet" />
</property>
<property name="allow_discussion">False</property>
<property name="default_view">view</property>
<property name="view_methods">
<element value="view"/>
</property>
<alias from="(Default)" to="(dynamic view)"/>
<alias from="edit" to="atct_edit"/>
<alias from="sharing" to="##sharing"/>
<alias from="view" to="(selected layout)"/>
<action title="View" action_id="view" category="object" condition_expr=""
url_expr="string:${folder_url}/" visible="True">
<permission value="View"/>
</action>
<action title="Edit" action_id="edit" category="object" condition_expr=""
url_expr="string:${object_url}/edit" visible="True">
<permission value="Modify portal content"/>
</action>
</object>
I've run into this problem myself. The problem is that the your Archetype's factory is not yet properly registered by the time you are trying to create it.
That's why _queryFactoryMethod() returns None, as you found out.
The solution differs a bit on whether you are using Products.ZopeTestCase or the newer plone.app.testing as your testing framework.
However, in both cases you need to make sure that the add-on product that defines the Archetype (ConceptSheetFolder) that you are trying to create (via invokeFactory), has aready been installed.
When using Products.ZopeTestCase:
In the case that you are using Products.ZopeTestCase (and Products.PloneTestCase), you need to call
Products.ZopeTestCase.installProduct
You need to make sure that your installProduct call does not get deferred until after your test is called.
In Plone 4 this means that your installProduct call should not be in an #onsetup decorated function (although this will still work in Plone 3).
This mailing list discussion might further clear things up:
http://plone.293351.n2.nabble.com/invokeFactory-failing-on-Plone-4-PTC-but-working-on-Plone-3-td5755482.html
When using plone.app.testing:
If you are using plone.app.testing, you should call:
plone.testing.z2.installProduct
This should be done in the setUpZope method that you override from the PloneSandboxLayer.
For more info, read the description under setUpZope in plone.app.testing.helpers.py (Line 257)
https://github.com/plone/plone.app.testing/blob/2ef789f8173c695179b043fd4634e0bdb6567511/plone/app/testing/helpers.py

how to marshal object and return as a view (and not as JSP page) in spring + xstream

I'm trying to follow this tutorial and build a RESTful service that can un/marshal an object to/from XML.
http://www.stupidjavatricks.com/?p=54
The marshaller of choice in the article is xStream (I found it to be very easy to use and configure).
The point is, using STS -- Spring's own flavor of Eclipse bundled with tcServer -- I built a project based on the STS template of MVC. This is a legacy project started from Spring version 2.4, and I migrated it to version 3.0. So, the template created all the necessary XML markup, and I added my configuration to point the view to the correct object conversion (to the xstream marshaler).
Here is part of my bean that sends the object to a new view (copied out from the link):
<bean id="bookXmlView" class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean class="org.springframework.oxm.xstream.XStreamMarshaller">
<property name="autodetectAnnotations" value="true"/>
</bean>
</constructor-arg>
</bean>
It all worked nicely until I installed the latest STS version 2.5.2.RELEASE and created a new MVC project from a template. (The new template does not use urlrewrite.xml anymore, among some other changes).
I set the correct configuration 1 by 1 as the tutorial suggests, but now no matter what, the view is always directed to a JSP, so if my controller looks like this:
#RequestMapping(value = "/authors/{authorId}")
public ModelAndView getAuthorById(#PathVariable String authorId) {
Author author = bookService.getAuthorById(authorId);
ModelAndView mav =new ModelAndView("bookXmlView", BindingResult.MODEL_KEY_PREFIX+"author", author);
return mav;
}
It would always try to return to a author.jsp view and not the object as XML. I tried many things with no success. Any ideas why this happens and how to fix it?
UPDATE -------------------
As noted I added logs:
I set it as DEBUG level and discovered something:
DEBUG: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Rejected bean name 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor': no URL paths identified
DEBUG: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Rejected bean name 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor': no URL paths identified
DEBUG: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Rejected bean name 'org.springframework.context.annotation.internalRequiredAnnotationProcessor': no URL paths identified
DEBUG: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Rejected bean name 'org.springframework.context.annotation.internalCommonAnnotationProcessor': no URL paths identified
DEBUG: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Rejected bean name 'bookXmlView': no URL paths identified
Notice this line: Rejected bean name 'bookXmlView': no URL paths identified.
Searching this indicated maybe a clash between <mvc:annotation-driven /> and my autodetectAnnotations in the xstream settings?
Any case, after invoking the link, I got the following log entry. Notice it forwards the view to /WEB-INF/views/bookXmlView.jsp:
DEBUG: org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'appServlet' processing GET request for [/test/page_init]
DEBUG: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapping [/page_init] to HandlerExecutionChain with handler [test.test.test.HomeController#a087de] and 2 interceptors
DEBUG: org.springframework.web.servlet.DispatcherServlet - Last-Modified value for [/test/page_init] is: -1
DEBUG: org.springframework.web.bind.annotation.support.HandlerMethodInvoker - Invoking request handler method: public org.springframework.web.servlet.ModelAndView test.test.test.HomeController.getObject()
DEBUG: org.springframework.beans.factory.support.DefaultListableBeanFactory - Invoking afterPropertiesSet() on bean with name 'bookXmlView'
DEBUG: org.springframework.web.servlet.DispatcherServlet - Rendering view [org.springframework.web.servlet.view.JstlView: name 'bookXmlView'; URL [/WEB-INF/views/xmlView.jsp]] in DispatcherServlet with name 'appServlet'
DEBUG: org.springframework.web.servlet.view.JstlView - Added model object 'org.springframework.validation.BindingResult.books' of type [test.test.test.ObjectTest] to request in view with name 'bookXmlView'
DEBUG: org.springframework.web.servlet.view.JstlView - Forwarding to resource [/WEB-INF/views/xmlView.jsp] in InternalResourceView 'bookXmlView'
DEBUG: org.springframework.web.servlet.DispatcherServlet - Successfully completed request
Got it at last!
First I tried a different marshaller - JAXB2 but xstream should work as well.
Next thing is the definition - turns out for some reason the configuration uses this (wrong):
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
using only InternalResourceViewResolver
while definition for org.springframework.web.servlet.view.BeanNameViewResolver is ignored. The solution for that is to define them both in one bean called ContentNegotiatingViewResolver as follows:
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</list>
</property>
</bean>
<oxm:jaxb2-marshaller id="marshaller">
<oxm:class-to-be-bound name="com.mycompany.dashboard.Person" />
</oxm:jaxb2-marshaller>
<bean name="person" class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg ref="marshaller" />
</bean>
That configuration solved my problems and person object I played with was not directed to a JSP view but marshaller turn is to an XML:
#RequestMapping(value = "/person", method = RequestMethod.GET)
public ModelAndView addPerson() {
Person person = new Person();
person.setAddress("address 123");
person.setAge(50);
person.setName("Andrew");
System.out.println("new person: " + person);
ModelAndView mav = new ModelAndView("person",BindingResult.MODEL_KEY_PREFIX + "person",person);
return mav;
Hope it would help others in the future too.

Resources