Simple 1-N FK relationship woes - jdo

I'm trying to get a simple 1-N FK relationship working with DataNucleus JDO. I have classes GridDO and GridColumnDO with relevant getters and setters. I'm trying to establish that a grid has multiple columns. The entity_attribute (GridColumn) table has a FK column (named entity_id) to the entity (Grid) table's PK (also named entity_id). I worked off of the example code on the DataNucleus website. I can load the GridDO object, but when I try to get the columns, I get
Iteration request failed : SELECT 'com.mycompany.myapplication.data.GridColumnDO' AS NUCLEUS_TYPE,A0.DISPLAY_NAME,A0.COLUMN_ORDER,A0.PROPERTY_NAME,A0.ENTITY_ID,A0.ENTITY_ATTRIBUTE_ID,A0.VALUE_TYPE FROM ENTITY_ATTRIBUTE A0 WHERE A0.ENTITY_ID = ?
org.datanucleus.exceptions.NucleusDataStoreException: Iteration request failed : SELECT 'com.mycompany.myapplication.data.GridColumnDO' AS NUCLEUS_TYPE,A0.DISPLAY_NAME,A0.COLUMN_ORDER,A0.PROPERTY_NAME,A0.ENTITY_ID,A0.ENTITY_ATTRIBUTE_ID,A0.VALUE_TYPE FROM ENTITY_ATTRIBUTE A0 WHERE A0.ENTITY_ID = ?
...
Caused by: java.sql.SQLException: Parameter #1 has not been set.
Does anybody know what I might be doing wrong? I've been searching and banging at this for a while now, with no real luck. This is an excerpt from package-mssql.orm:
<class name="GridDO" identity-type="application" table="entity">
<field name="id" primary-key="true">
<column name="entity_id"/>
</field>
<field name="columns">
<collection element-type="com.mycompany.myapplication.data.GridColumnDO"/>
<element column="entity_id"/>
</field>
...
</class>
<class name="GridColumnDO" identity-type="application" table="entity_attribute">
<field name="id" primary-key="true">
<column name="entity_attribute_id"/>
</field>
...
</class>

The issue was that PersistenceCapable and PrimaryKey must either both be identified via annotations or both be identified via metadata. I had PersistenceCapable in an annotation and PrimaryKey in my .orm file.

Related

How to find all Node Ref's which are using custom aspect property with CMIS 1.1?

We have created custom property using custom content model. We need to fetch below information from the custom content model. We are using alfresco 4.2.2;
How can we find all Node Ref's which are having the cc:productstatus property using CMIS 1.1?
and then how to delete that property for these nodeRef's using Java.
<namespaces>
<namespace uri="http://www.custom.co/model/product/1.0" prefix="cc"/>
</namespaces>
<aspects>
<aspect name="cc:product">
<title>Status</title>
<parent/>
<properties>
<property name="cc:productstatus">
<title>status</title>
<type>d:text</type>
</property>
</properties>
</aspect>
</aspects>
Just select from an aspect same like from a type:
SELECT *
FROM cc:product as p
WHERE
p.cc:productstatus is not null
and JOIN if you need e.g. use two aspects:
SELECT *
FROM app:inlineeditable as d
JOIN cm:titled as p on d.cmis:objectId = p.cmis:objectId
WHERE
d.app:editInline = true and
p.cm:title like 'categorysearch.get.html.404.ftl'
now you can use nodeService to remove aspect.

The SPListItem being updated was not retrieved with all taxonomy fields

I have added document library template using VS 2012. and then added custom content types to this library. the content types includes 3 managed metadata fields. After deploying the project when I add terms to taxonomy fields in document library, I got following error:
"The SPListItem being updated was not retrieved with all taxonomy fields"
I could not find any solution. Any body have an idea whats wrong ?
In the ELEMENTS.XML file of the contenttype your field (actually you need TWO, note how they are linked togheter) must be something like:
<Field Type="Note"
ID="{4B53F593-CF60-40DF-AEAF-23155BB9AA3F}"
DisplayName="_Circular_Tags"
Name="Circular_Tags_NOTE"
StaticName="Circular_Tags_NOTE"
ShowInViewForms="FALSE"
Required="FALSE"
Hidden="TRUE"
CanToggleHidden="TRUE"
RowOrdinal="0">
</Field>
<Field Type="TaxonomyFieldTypeMulti"
ID="{DF553026-F699-456F-AA24-0C6087DBE885}"
Name="Circular_Tags"
StaticName="Circular_Tags"
DisplayName="Circular_Tags_DisplayName"
Description="Circular_Tags_Description"
ShowField="Circular_Tags_Path"
Required="FALSE"
Sortable="FALSE"
AllowDeletion="TRUE"
EnforceUniqueValues="FALSE"
ShowInViewForms="TRUE"
Group="MyContentTypes_Group">
<Default></Default>
<Customization>
<ArrayOfProperty>
<Property>
<Name>TextField</Name>
<Value xmlns:q6="http://www.w3.org/2001/XMLSchema" p4:type="q6:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">{4B53F593-CF60-40DF-AEAF-23155BB9AA3F}</Value>
</Property>
</ArrayOfProperty>
</Customization>
</Field>
Then you need (in the feature-activated code) do the following:
SPSite site = properties.Feature.Parent as SPSite;
Guid fieldId = new Guid("{DF553026-F699-456F-AA24-0C6087DBE885}");
if (site.RootWeb.Fields.Contains(fieldId))
{
TaxonomySession session = new TaxonomySession(site);
if (session.TermStores.Count != 0)
{
var termStore = session.TermStores["ManagedMetadata_Proxy"];
var group = termStore.Groups["GroupName"];
var termSet = group.TermSets["TermSetName"];
TaxonomyField field = site.RootWeb.Fields[fieldId] as TaxonomyField;
//set the text field to the id of the _Circular_Tags field : 4B53F593-CF60-40DF-AEAF-23155BB9AA3F
field.TextField = new Guid("{4B53F593-CF60-40DF-AEAF-23155BB9AA3F}");
// Connect to MMS
field.SspId = termSet.TermStore.Id;
field.TermSetId = termSet.Id;
field.TargetTemplate = string.Empty;
field.AnchorId = Guid.Empty;
field.Update();
}
}
Finally in the SCHEMA.XML file in the List definition you should have a definition like this for the field:
<Field Type="TaxonomyFieldType" ID="{DF553026-F699-456F-AA24-0C6087DBE885}" Name="Circular_Tags" StaticName="Circular_Tags" DisplayName="Circular_Tags_DisplayName" Description="Circular_Tags_Description" ShowField="Circular_Tags_Path" Mult="TRUE" Required="FALSE" Sortable="FALSE" AllowDeletion="TRUE" EnforceUniqueValues="FALSE" ShowInViewForms="TRUE" Group="ContentTypes_Group">
<Default></Default>
<Customization>
<ArrayOfProperty>
<Property>
<Name>TextField</Name>
<Value xmlns:q6="http://www.w3.org/2001/XMLSchema" p4:type="q6:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">{4B53F593-CF60-40DF-AEAF-23155BB9AA3F}</Value>
</Property>
</ArrayOfProperty>
</Customization>
</Field>

get auto-genearated key for the inserted record in mybatis

I am working under a web application which use spring mvc + mybatis + mysql.
And I found that I can not get the auto-generated key for the last inserted record (I have googled so much).
This is the related configuration(take the model 'Post' for example):
spring.xml:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
//omitted
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="config.xml" />
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
mybatis config.xml
<configuration>
<typeAliases>
<typeAlias alias="Post" type="com.king.model.Post" />
</typeAliases>
<mappers>
<mapper resource="com/king/model/PostMapper.xml" />
</mappers>
</configuration>
PostMapper.xml:
<mapper namespace="com.king.model.PostMapper">
<insert id="insert" parameterType="Post">
insert into posts (title,body,created_at,updated_at) values (#{title},#{body},#{createDate},#{updateDate})
</insert>
</mapper>
Dao:
public abstract class AbstractSimpleDaoImpl<T> extends SqlSessionDaoSupport{
#Override
public int add(T entity) {
return getSqlSession().insert(getMapperNamespace() + ".insert", entity);
}
protected abstract String getMapperNamespace();
}
public class PostDao extends AbstractSimpleDaoImpl<Post> {
#Override
protected String getMapperNamespace() {
return "com.king.model.PostMapper";
}
}
However,when I insert a new Post to database:
postDao.add(post);
I can not get the generated id for the inserted post. I always get 1. I know this is the row-affected number.
Also,I read the mybatis guide,and I tried this:
<insert id="insert" parameterType="Post" useGeneratedKeys="true" keyProperty="id">
But it seems that,this does not work.
How to fix it?
In fact the following works:
<insert id="insert" parameterType="Post" useGeneratedKeys="true" keyProperty="id">
postDao.add(post);
will return 1 as before,but post.getId() will get the key.
This can be done using annotations as well.
final String INSERT = "insert into posts (title,body,created_at,updated_at) values (#{title},#{body},#{createDate},#{updateDate})";
#Insert(INSERT)
#Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
void insert(Post post) throws Exception;
Set keyProperty as the Java variable name.
Set keyColumn as the column name in the database.
After insert, post.getId() will have your generated ID.
Try using the following code; I added the keyColumn field to your code:
<insert id="insert" parameterType="Post" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
Alternatively, if you are using PostgreSql:
<insert id="insert" parameterType="Post" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
<selectKey keyProperty="id" resultType="java.lang.Integer">
SELECT
currVal('your_tbl_seq') as id
</selectKey> </insert>
This will work for Spring Boot using annotations and getting the id as a return value as in your original question.
#Insert("insert into sources (host, created_at) values (#{host}, now())")
#SelectKey(statement="select LAST_INSERT_ID()", keyProperty="id", before=false, resultType=long.class)
long create(#Param("host") String host);
Then long id = sourceMapper.create("abc"); would return your primary key.

Apache Solr: Faceted Search on multivalued fields

Im currently working on a solr based search application.
I have two multivalued fields for example:
The data is read out of a database.
<int name="id">1</int>
<arr name="type">
<str>Marke</str>
<str>Modell</str>
<str>Fahrzeugtyp</str>
<str>engine</str>
</arr>
<arr name="value">
<str>Volkswagen</str>
<str>Golf</str>
<str>Golf TDI</str>
<str>V-Engine</str>
In my current solr configuration there is no relationship between these two multivalued fields. So that i can say "Marke = Volkswagen".
Besides there must be a relationship between Volkswagen and Golf. So I have to structure a taxonomy out of the two multivalued fields and of the values in the multivalued field itself.
I tried to build a typeAhead. In my current config when i search for Volkswagen - the possible suggestions contain audi and engine2 which does not refer to a Volkswagen model.
solr url:
http://xyz:8983/solr/suggest?&wt=json&facet=true&q=*&facet.field=value&facet.prefix=Volkswagen
I think Solr Faceting on Multiple Concatenated Fields has something to do with it, but I can't adjust it on my problem.
Thanks in reply
Maybe I can use the TemplateTransformer to combine value and type?
With TemplateTransformer I get a result: Marke | Volkswagen
In my data-import.xml (DIH)
<entity> name="tablename" transformer="TemplateTransformer">
<field column="test" template="${tablename.TYPE} | tablename.VALUE}"/>
...
</entity>
It has been a long time since I've solved this problem. Try use this script in your data input handler. Attention - this script is based on solr 3.6.
<script>
<![CDATA[ function f1(row)
{
var eldName = row.get('TYPE');
row.put(eldName, row.get('VALUE'));
return row;
}
]]>
</script>
<entity name="e" transformer="script:f1" query="select TYPE, VALUE from X"></entity>

Incorrect component when querying immediately after insert using NHibernate

I have the following mapping for my table in MySql:
<class name="Tag, namespace" table="tags" >
<id name="id" type="Int32" unsaved-value="0">
<generator class="native"></generator>
</id>
<property name="name" type="String" not-null="true"></property>
<component name="record_dates" class="DateMetaData, namespace" >
<property name="created_at" type="DateTime" not-null="true"></property>
<property name="updated_at" type="DateTime" not-null="true"></property>
</component>
</class>
As you see the record_dates property is defined as a component field of type DateMetaDate. Both created_at and updated_at fields in 'tags' table are updated via triggers. Thus I can insert a new record like such:
var newTag = new Tag()
{
name = "some string here"
}
Int32 id = (Int32)Session.Save(tag);
Session.Flush();
ITag t = Session.Get<Tag>(id);
ViewData["xxx"] = t.name; // -----> not null
ViewData["xxx"] = t.record_dates.created_at; // -----> is null
However when querying the same record back immediately after it was inserted the record_dates field ends up null even though in the table those fields have got values.
Can any one please point out why the Session.Get ignores getting everything back from the table? is it because it caches the newly created record for which the records_dates is null? If so how can it be told to ignore the cached version?
Try using lazy="false" in your class tag:
<class name="Tag, namespace" table="tags" lazy="false">
As per my knowledge, the default behavior is to have lazy loading, which might not refresh your objects as needed.
The only I so far have found is to call Session.Clear() method on the NHibernate session object, which I guess forces NHibernate to fetch the record from the table again. But I'm afraid it removes everything in cache and thus be inefficient.
You can call ISession.Refresh(obj) to force the object to be reloaded from the database. My understanding is that this will not refresh all relationships, so if you need to reload the complete object graph, call ISession.Evict(obj) then ISession.Get(id) to remove it from the cache and reload it.

Resources