Transient annotation and error executing DDL - postgresql

I use the annotation # trasient to declare a boolean variable but when I start my spring application, I got the error as below
Error executing DDL "
alter table categories
add column has_children boolean not null" via JDBC Statement
This indicates that the column of has_children should not be null but Im not sure how to set the default of boolean value to false. Any ideas ? Thanks
----Edit-----
Below is my entity code
#Transient
private boolean hasChildren;
public boolean isHasChildren() {
return hasChildren;
}
public void setHasChildren(boolean hasChildren) {
this.hasChildren = hasChildren;
}

You didn't provide the code showing the entity, but just a heads up.
The default value of a boolean (primitive) is false, but the default value of a Boolean (the wrapper class) is null.
So it's worth checking if your variable has_children is created using Boolean instead of boolean

Related

JPA StoredProcedureQuery: pass UUID as a parameter

I use JPA 2.1 (Hibernate), Postgres 9.6, and I need to pass java.util.UUID as a parameter to StoredProcedureQuery like this:
StoredProcedureQuery proc = em.createStoredProcedureQuery(myProc)
.registerStoredProcedureParameter(0, UUID.class, ParameterMode.IN)
.registerStoredProcedureParameter(1, ...)
.setParameter(0, myUuid)
.setParameter(1, ...);
By default, the Java type UUID is interpreted as Postgres type bytea and I get something like:
ERROR: function my_function(bytea, ...) does not exist.
Of course it does not exist, because my function is:
my_function(UUID, ...)
So, is there any way to define explicitly, which database-level type must be used for a particular parameter?
Might be something like the one we use in entity classes with the annotation:
#Type(type="pg-uuid")
private UUID uuid;
One obvious workaround is to pass the value as a String, and then cast it to UUID inside the function, but...
With EclipseLink 2.7.6 and Postgres 11.8 it works, I expect it should work with Hibernate too; originally I ended with the "bytea" too. First I needed this trivial converter, I have no idea why I have to convert UUID to UUID, but it works.
import java.util.UUID;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
#Converter(autoApply = true)
public class UUIDConverter implements AttributeConverter<UUID, UUID> {
#Override
public UUID convertToDatabaseColumn(final UUID uuid) {
return uuid;
}
#Override
public UUID convertToEntityAttribute(final UUID uuid) {
return uuid;
}
}
The function api is this:
create or replace function generate_namespace(idSubscription uuid) returns integer as
...
Just a side note - I wasn't able to return the whole record as managed entity, because JPA will not receive all required metadata and does not know what (and if) is the primary key etc. So instead of returns Namespace I return only it's primary key and then I call entityManager.find to get the managed entity generated by the function:
final StoredProcedureQuery query = manager.createStoredProcedureQuery("generate_namespace");
query.registerStoredProcedureParameter(1, UUID.class, ParameterMode.IN);
query.setParameter(1, idSubscription);
final Object[] result = (Object[]) query.getSingleResult();
return manager.find(Namespace.class, result[0]);

Nullable Guid Parameter in RAW method Codefluent Entities

I have a RAW method for an entity that has GUIDS as parameters.
LOADONE (Guid CwObjectGuid, Guid CountryGuid) RAW
With the corresponding body:
SELECT * FROM dbo.Bid
WHERE Bid_CwObject_Guid = #CwObjectGuid
AND ((Bid_CountryGuid = #CountryGuid) OR (#CountryGuid = '00000000-0000-0000-0000-000000000000' AND Bid_CountryGuid IS NULL))
The parameter CountryGuid can be a default Guid. However, the method that is generated checks whether the parameter is a default. In that case the method will return NULL.
if ((countryGuid.Equals(CodeFluentPersistence.DefaultGuidValue) == true))
{
return null;
}
I don't want that check. Can I somehow prevent it?
By default, the property is not nullable, so CodeFluent check if the value is equals to the default value (see Simon's answer). You can disable this behavior by setting usePersistenceDefaultValue to false:
<cf:method name="load" body="LOADONE(...) RAW" rawBody="...">
<cf:parameter name="countryGuid" usePersistenceDefaultValue="false"/>
</cf:method>
You can also send nullable guid to the database
<cf:method name="load" body="LOADONE(Guid? id) RAW" rawBody="..." />

JPA entity with column of type long that have a Null value

I'm new to JPA . I'm using spring data and I want to create an entity "File" (a folder is a File ) . each File can have a parent (or not).
this is my table's columns :id ,name,path ,mtime ,parentid.
I used this in my entities
#ManyToOne
#JoinColumn(name = "parentid")
private File parent;
public File() {}
public File(String name, String path,File parent) {
this.name = name;
this.path=path;
this.parent=parent;
}
#Override
public String toString() {
return String.format(
"File[ id=%d,name='%s', path='%s',parentid=%d]",
id,name, path,parent.id);
}
in my test I did this :
fileRepository.save(new File("file1","file1",null));
File file1=fileRepository.findOne((long) 1);
fileRepository.save(new File("file2","file2",file1));
and it inserted the first line with parentid NULL and a second line with parentid 1 (the first file).( I confirmed that on phpmyadmin)
I wanted to show the lines so i did this :
for (Object element : Lists.newArrayList(fileRepository.findAll())) {
System.out.println(element);
}
but it doesn't work .
when I removed parentid from my toString() function I get the correct result :
File[ id=1,name='file1', path='file1']
File[ id=2,name='file2', path='file2']
I get the same problem if I add a new column of type Long and when one of the lines have a NULL value in that column .
how Can I fix that ?
Your toString() method "doesn't work" because you're trying to get the id of a null parent, which obviously causes a NullPointerException. You need to test if the parent is null before trying to get and print its ID. Reading the message, type and stack trace of the exception would have allowed you to find this out. Using a debugger as well.
A variable of type long can't hold null. Primitive types are not nullable. So you need to use the type java.lang.Long for this field.

Code First Entity Framework

We are using Miscrosoft's code first entity framework (4.1) to map to an existing database. We want to be able to change the datatypes and values of some properties that map one to one with a table. For instance, there is a column on the table that determines if a record is current. It is an integer column, and has values 1 or 2. We don't want to change the database as there are many different applications fetching data from that colum, but it would be nice for our code to have the class that maps to that table have a bool property that is IsActive, which returns true if the table column is 1 and false otherwise. Is there a way to configure the EnityFrame work so that we can define this mapping directly without having two properties on the actual class, one for the integer column (mapped to the database) and one boolean property computed from the other? Can I map the boolean property directly to the integer column?
Simple answer is no. EF is totally stupid in this area and it is completely missing simple type mapping.
That means that you cannot change type of scalar properties and your class indeed has to work with that int property using values 1 and 2 to define your IsActive.
The workaround can be:
public class YourClass
{
public int IsActiveValue { get; set; }
[NotMapped]
public bool IsActive
{
get { return IsActiveValue == 2; }
set { IsActiveValue = value ? 2 : 1; }
}
}
This workaround has some disadvantages
You must have two properties and IsActvieValue must be visible to context
You cannot use IsActive in linq-to-entities queries

Exposing enum typed properties for entity framework entities fields in ADO.NET Data Service client context

I have an entity with fields that are typed int
and i want to exposed those fields as properties which get and recieve enum type values for working strongly typed.
so i've created a new partial class for the entity and added the two properties.
when i try to create a new instance of the TestEntity and add it to the context ,
and call save changes i get the following exception:
An error occurred while processing this request.
at System.Data.Services.Client.DataServiceContext.SaveAsyncResult.HandleBatchResponse()
at System.Data.Services.Client.DataServiceContext.SaveAsyncResult.EndRequest()
at System.Data.Services.Client.DataServiceContext.SaveChanges(SaveChangesOptions options)
at System.Data.Services.Client.DataServiceContext.SaveChanges()
the inner exception is:
System.InvalidOperationException: The type 'enum1' has no settable properties.
at System.Data.Services.Client.ClientType..ctor(Type type, String typeName, Boolean skipSettableCheck)
at System.Data.Services.Client.ClientType.Create(Type type, Boolean expectModelType)
at System.Data.Services.Client.DataServiceContext.WriteContentProperties(XmlWriter writer, ClientType type, Object resource)
at System.Data.Services.Client.DataServiceContext.CreateRequestData(ResourceBox box, Boolean newline)
at System.Data.Services.Client.DataServiceContext.SaveAsyncResult.CreateChangeData(Int32 index, Boolean newline)
at System.Data.Services.Client.DataServiceContext.SaveAsyncResult.BeginNextChange(Boolean replaceOnUpdate)
so i figured it tries to reflect the enum properties as classes properties.
how can i make the context ignore those properties when it tries to reflect on them.
i am using VS 2008 team suite sp1 , SQL Server 2008 , .Net 3.5 Sp1.
Help.
the partial class code:
public partial class TestEntity
{
public enum1 Field1
{
get
{
return (enum1)field1;
}
set
{
field1 = (Int16)value;
}
}
public enum2 Field2
{
get
{
return (enum2)field2;
}
set
{
field2 = (Int16)value;
}
}
}
I don't think that you can. In ADO.Net Data Services, you can't have enums on your proxy objects that get sent up to the server. Try changing your object around to use an int (or short) instead.