Where are tables that generated database by Liferay through service.xml?. I don't see it in my Postgres. There are so many tables, I tried to find it but it not found. Anyone can help me, thanks
Unless you explicitly specify the table name in the entities that you declare in service.xml, the table names are constructed with the namespace and entity name.
<service-builder package-path="com.liferay.docs.guestbook">
<namespace>GB</namespace>
<entity name="Guestbook" local-service="true" uuid="true">
...
would generate GB_Guestbook as table name.
From the very well documented DTD:
<namespace>
The namespace element must be a unique namespace for this component.
Table names will be prepended with this namespace. Generated JSON
JavaScript will be scoped to this namespace as well (i.e.,
Liferay.Service.Test.* if the namespace is Test).
<entity> Child of service-builder
An entity usually represents a business facade and a table in the
database. If an entity does not have any columns, then it only
represents a business facade. The Service Builder will always generate
an empty business facade POJO if it does not exist. Upon subsequent
generations, the Service Builder will check to see if the business
facade already exists. If it exists and has additional methods, then
the Service Builder will also update the SOAP wrappers.
If an entity does have columns, then the value object, the POJO class
that is mapped to the database, and other persistence utilities are
also generated based on the order and finder elements.
...
(and you'll find more hints, e.g. explicit table names, in that document)
Notes:
If you declare that the entities are stored in an external (non-Liferay) datasource, no tables will be created.
Also, some versions of Liferay automatically updated the database structure on deployment of a new plugin version (with updated persistence layers), while others don't do this automatically (it's a developer feature anyways, not good for large - production - amount of data)
Related
Using Hibernate Search 5.11.3 with programmatic API (no annotations), is there a way to facet on dynamic fields added in a class or field bridge? I don't see any 'facet' config available in FieldMetadataBuilder when using MetadataProvidingFieldBridge.
I have tried various combinations of luceneOptions.addSortedDocValuesFieldToDocument() and luceneOptions.addFieldToDocument() in the set() method. This successfully updates the index, but I cannot perform facet queries.
I am trying to do a basic attribute facet/filter where I have a generic table of attributes with id/name and attribute values associated with products. For various reasons I am using the programmatic API and especially for attributes I can't make use of the #Facet annotation. So for a product, I added this class bridge to Product.class:
public class ProductClassTagValuesBridge implements FieldBridge
{
#Override
public void set(String name, Object value, Document document, LuceneOptions luceneOptions)
{
Product product = (Product) value;
for (TagValue v : product.getTagValues())
{
Tag tag = v.getTag();
String tagName = "tag-" + tag.getId();
String tagValue = v.getId().toString();
// not sure if this line is required? Have tried with and without
luceneOptions.addFieldToDocument(tagName, tagValue, document);
luceneOptions.addSortedDocValuesFieldToDocument(tagName, tagValue, document);
}
}
}
Then I build my (test) faceting request to search tag-56 (which I confirmed is in the index using Luke):
FacetParameterContext context = queryBuilder.facet()
.name("tag-56")
.onField("tag-56")
.discrete();
FacetingRequest facetingRequest = context.createFacetingRequest();
Which when used in the search/FacetManager gives me the error:
org.hibernate.search.exception.SearchException: HSEARCH000268: Facet request 'TAG_56' tries to facet on field 'tag-56' which either does not exist or is not configured for faceting (via #Facet). Check your configuration.
I have also tried the custom config solution from the solution in this post: Hibernate Search: configure Facet for custom FieldBridge
For the custom field I added a field bridge to tagValues on my product. The same error occurs.
mapping.entity(Product.class).indexed()
.property("tagValues", ElementType.FIELD).field()
.analyze(Analyze.NO).store(Store.YES)
.bridge(ProductTagValuesFieldBridge.class)
Short answer: Hibernate Search does not allow that... yet.
Long answer:
Hibernate Search 5 allows dynamic fields, but does not allow faceting on fields declared in custom bridges.
That is to say, you can add arbitrary values to your index that don't fit a pre-defined schema, but you cannot use faceting on those fields.
Hibernate search 6 allows faceting (now called "aggregations") on fields declared in custom bridges (just declare them as .aggregable(Aggregable.YES)), but does not allow dynamic fields yet.
EDIT: Starting with 6.0.0.Beta7, dynamic fields are supported thanks to field templates. So the rest of my message is not useful anymore.
See this section of the documentation for more information about field templates. It's totally possible to declare an aggregable, dynamic field in your bridge.
Original message about ways to work without dynamic fields (obsolete):
That is to say, if you know the list of tags upon startup, are able to list them all, and are certain they won't change while your application is up, you could declare the fields upfront and use faceting on them. But if you don't know the list of tags upon startup, none of this is possible (yet).
Until dynamic fields are added to Hibernate Search 6, the only solution is to use Hibernate Search 5 and to re-implement faceting yourself. As you can expect, this will be complex and you will have to get your hands dirty with Lucene. You will have to:
Add fields of type SortedSetDocValuesFacetField to your document in your custom bridge.
Ensure Hibernate Search calls FacetsConfig.build on your documents after they are populated. One way to do that (through a hack) would be to declare a dummy #Facet field on your entity, even if you don't use it.
Completely ignore Hibernate Search's query feature and perform faceting yourself from an IndexReader. You can get an IndexReader from Hibernate Search as explained here. There's an example of how to perform faceting in org.hibernate.search.query.engine.impl.QueryHits#updateStringFacets.
I am newbie to Liferay. I would like to build with Service Builder the following column for the entity Traveller:
<entity name="Traveller" local-service="true" remote-service="true">
<column name="citiesList" type="Collection"></column>
</entity>
When I run the service Builder, in the class TravellerModel.java the corresponding get/set methods are not generated.
I have tried the following solution without success:
<column name="citiesList" type="Collection" entity="java.lang.String"></column>
Can someone tell me how I can define a list of Strings (List) in Liferay Service Builder?
Thanks in advance.
(Closing an old thread..)
List is not a field you can simply create on Service builder by declaring it, as the rational is the same you would probably use when thinking about a DB schema, you would normally create an auxiliary table with foreign keys and values, or embed the data in a single data field to be encoded (not great).
On SB, though, you can using mapping tables or an extra entity to reformulate your list representation. Besides that you can add Lists as a parameter on you LocalServiceImpl class that consumes or build lists in a higher level.
I have several database tables that my Spring MVC/JPA application refers to using the #Entity and #Table Annotations. I've run into the issue where if my application switches between database connections, some tables that exist on database 1 may not exist in database 2 (as we are following the SDLC cycle and promoting table additions/changes after they get the "OK"), thus resulting in an SQL Exception when the application server starts.
Does spring offer a way to mark specific #Entity Classes as "Optional" or "Transactional" so there are no database Exceptions returned because of nonexistant tables?
In my opinion, there is no option to do that.
You can add automatic update of schema in Hibernate, but you mentioned that you are doing this manually.
Hibernate is validating the schema, when he establishes connection. You use #Entity, so he looks for that table and throws an error if there is no with the name specified.
I have tables that have this annotation structure in my application and I use JpaRepository for CRUD operations.
#Entity
#Table(name = "FOO")
public class Foo implements Serializable {
…
}
But I need to override only the table name (not any of the #Column etc. attributes) from an orm.xml or properties file without changing the actual code. I've searched and I couldn't find a way to do it in Spring Data JPA. Am I missing something here or it is not supported?
Firstly, Spring Data is not a JPA provider but simply a 'helper' library providing a wrapper round common persistence operations. The JPA specification however does provide a mechanism for overriding annotations via an XML mapping file. So assuming your provider (Hibernate, EclipseLink, OpenJPA or whatever) fully implements the JPA specification then you should be able to do this.
However it would appear that you cannot override only the table name: unless your column names are mapped to the default values then, as far as I can see, you need to specify each column in the mapping file - which is slightly inconvenient I suppose.
The book Pro JPA 2 : Mastering the Java Persistence API notes:
The metadata-complete attribute is an attribute on the entity,
mapped-superclass, and embeddable elements. If specified, all
annotations on the specified class and on any fields or properties in
the class will be ignored, and only the metadata in the mapping file
will be considered as the set of metadata for the class. When
metadata-complete is enabled, the same rules that we applied to
annotated entities will still apply when using XML-mapped entities.
For example, the identifier must be mapped, and all relationships must
be specified with their corresponding cardinality mappings inside the
entity element.
So you will need an entry in your orm.xml like the below, adding other attributes as required.
<entity-mappings>
<entity class="examples.Foo" metadata-complete="true">
<table name="NEW_FOO"/>
<attributes>
<id name="id"/>
</attributes>
</entity>
</entity-mappings>
I use Hibernate Reverse Engineering to automatically create classes from a database scheme. DB server is MSSQL 2008. This database is designed by a partner and could potentially change without notice. Thus I'd like to have Hibernate validate the scheme on startup, wich in my opinion should work out of the box. But it doesn't:
org.hibernate.HibernateException: Wrong column type in somedb.dbo.ASVC_S for column SomeCol. Found: decimal, expected: numeric(18,0)
The generated enttity class looks like this:
#Column(name="SomeCol", precision=18)
public BigDecimal getSomeCol() {
return this.someCol;
}
Is my assumption that reveng creates classes that can be validated against the schema wrong? Should I skip validation and hope that during runtime everything's OK? Annotating the classes after generating them or maintaining an entry for each class in my reveng.xml mapping file is not an option - too many classes ;)
hibernate-tools is version 4.0.0-CR1.