Spring Hibernate MySQL Unidirectional ManyToOne - java

I have two (very simple) entities: Parent and Child.
#Entity
class Child {
#Id
#Column(name = "id", nullable = false, updatable = false, columnDefinition = "BINARY(16)")
private UUID id;
#Column(columnDefinition="varchar(4000)")
private String obs;
#NotNull
#ManyToOne(optional = false)
#JoinColumn(nullable = false, updatable = false)
private Parent parent;
(getters and setters)
}
The original obs field had no annotation, so Hibernate created it as a varchar(255), but I needed it to be able to handle a larger text. After the changes (as shown above), the method getParent() always returns null.
Does anyone have any idea why this is happening?

For your Column annotation, rather than using columnDefinition set the length element. Here is the Javadoc of length:
(Optional) The column length. (Applies only if a string-valued column is used.)
Default:
255
You can also see why it defaulted to VARCHAR(255) in your schema: the default is 255. Why your columnDefinition doesn't work, however, I don't know (I've no experience with it).

Related

best practice for implement ManyToOne

I always use the following method to implement ManyToOne in class :
#Column(name = "buyer_id")
private Long buyerId;
#ManyToOne
#JoinColumn(name = "buyer_id", insertable = false, updatable = false)
UserGroup buyer;
However, I have a question whether it is better to use the following code:
#ManyToOne
#JoinColumn(name = "buyer_id", insertable = false, updatable = false)
UserGroup buyer;
or not?
In the first case, I always set the id value obtained in buyerId for saving after saving the UserGroup, but in the second case, I put the userGroup model completely (after save) in my entity then save entity.
I'm not sure if the method I use is the best.
I searched the internet but could not find a technical reason that the latter is not appropriate.

JPA Hibernate uses #NotNull Annotation on Getter despite using #Access(value=AccessType.FIELD)

I have an Entity that uses
#Entity
#Table(
indexes = {#Index(name="URL_PARAMETER_INDEX", unique = true, columnList = "urlParameter")}
)
#Access(value=AccessType.FIELD)
public class EntityA extends UniqueIdEntity {
// From #MappedSuperClass "UniqueIdEntity"
#Id
#GeneratedValue(generator = "uuid2")
#Column(unique = true, updatable = false, columnDefinition = "uuid")
protected UUID id;
#Column(name = "urlParameter", unique = true, nullable = true)
private String urlParameter;
...
#javax.validation.constraints.NotNull
public String getUrlParameter() {
if(this.urlParameter == null) {
this.urlParameter = this.calculateUrlParameter();
}
return urlParameter;
}
}
While the field urlParameter can be null, on first access it is generated and the newly generated value is returned, thus the field may be null, but the getter will never return null.
However, JPA translates this into the following DDL command: add column url_parameter varchar(255) not null and when I remove the #NotNull annotation on the getter it generates the column as nullable.
What am I doing wrong? I already added the #Access(value=AccessType.FIELD) on every super class to make sure JPA/Hibernate are using the correct access type.
How can I assure that the Column is nullable, while still having the #NotNull Annotation on my Getter?

how to address a database column multiple times using hibernate

I have a project to access a database via REST, in which an old database has to be addressed in a modern way using javax.persistence annotations and JPA.
One of my classes fields look like this:
#Column(name = "properties_id", nullable = false)
private int propertiesId;
#Id
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "properties_id", referencedColumnName = "dbid", insertable = false, updatable = false)
private PropertyList propertyList;
#Id
#Column(name = "propertiesIdx", nullable = false)
private int propertiesIdx;
As you can see in the fields, the column properties_id is used as part of the primary key and as a foreign key. Unfortunately, there is no possibility to change the database layout.
In the application, I need both fields: one for joining the parent-table and another for addressing the property directly.
But in the way it is currently implemented, it doesn't work.
Does somebody have an idea how to address this problem?
For further details of the problem please feel free to visit the git-repo:
https://github.com/SerNet/verinice-rest-service/tree/import

How do I implement an "optional" relationship in Hibernate/JPA?

I'm using the Hibernate 3.6 implementation of JPA. I have two tables in a logical parent-child relationship. Normally there would be one record in the "child" for each record in the "parent." The tables look like this:
CREATE TABLE FOO (
FOO_ID INT IDENTITY,
BAR_ID INT DEFAULT 0 NOT NULL,
SOMEDATA CHAR(50) );
CREATE TABLE BAR (
BAR_ID INT IDENTITY,
OTHERDATA CHAR(50),
STILLOTHER CHAR(50)) ;
However, it has been decided that some "parent" records should not have "child" records and I should just put a 0 in the FOO.BAR_ID column.
How do I implement this in my entity classes? Right now the classes look like this:
public class Foo implements java.io.Serializable {
#Id
#GeneratedValue
#Column(name = "FOO_ID", unique = true, nullable = false)
private Long fooId;
#OneToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST})
#JoinColumn(name = "BAR_ID", nullable = false)
private Bar bar;
}
public class Bar implements java.io.Serializable {
#Id
#GeneratedValue
#Column(name = "BAR_ID", unique = true, nullable = false)
private Long barId;
)
I can't seem find the right syntax to place a 0 in the FOO.BAR_ID column and not try to create a record in the BAR table. Can this even be done with Hibernate?
#OneToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST})
#JoinColumn(name = "BAR_ID", nullable = false)
I believe you should try removing.
nullable = false
You are telling hibernate that Foo's Bar can not be null. If Bar is optional then sometimes it must be null. Since it can not be null and the CascadeType is Persist, Hibernate is saving the Bar that Foo must have when you save Foo.

Netbeans - Glassfish server deployment error due to composite primary key

I'm currently having an issue with a BUILD FAILED error when deploying my Netbeans project to Glassfish server. I get the following error from the log:
Exception Description: The #JoinColumns on the annotated element [field instrument] from the entity class [class entity.InstrumentExtRef] is incomplete. When the source entity class uses a composite primary key, a #JoinColumn must be specified for each join column using the #JoinColumns. Both the name and the referencedColumnName elements must be specified in each such #JoinColumn.. Please see server.log for more details.
The table that's having the issue is instrument_ext_ref and has a composite primary key of the following fields: instrument_id and instrument_code_type.
The entity class that seems to have the problem - InstrumentExtRef - has the following declarations and annotations.
#EmbeddedId
protected InstrumentExtRefPK instrumentExtRefPK;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 16)
#Column(name = "reference")
private String reference;
#JoinColumn(name = "instrument_code_type", referencedColumnName = "code_type", insertable = false, updatable = false)
#ManyToOne(optional = false)
private InstrumentCodeType instrumentCodeType1;
#JoinColumn(name = "instrument_id", referencedColumnName = "id", insertable = false, updatable = false)
#ManyToOne(optional = false)
private Instrument instrument;
And the entity class containing the #EmbeddedId details (InstrumentExtRefPK) looks like this:
#Embeddable
public class InstrumentExtRefPK implements Serializable {
#Basic(optional = false)
#NotNull
#Column(name = "instrument_id")
private int instrumentId;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 10)
#Column(name = "instrument_code_type")
private String instrumentCodeType;
Class InstrumentCodeType refers to table instrument_code_type which has a primary key code_type (the referenced column). Class Instrument refers to table instrument which itself has a composite primary key consisting of columns "id" (the referenced column) and column "exchange_exchange_code".
It seems obvious from the error message that the composite primary key in the InstrumentExtRef entity is the issue but based on my research of other similar (but not quite the same) issues I think my entity classes look OK. But I'm relatively new to this and may be missing something.
After doing some more research on creating/uses of composite keys in entity classes I saw a subtle point in the error message I was receiving.
"...must be specified for each join column using the #JoinColumn*s*". I wasn't using the #JoinColumns annotation. Or at least Netbeans didn't create the entity class that way. Probably because each join column is from a different source entity/table.
After correcting my entity classes as follows the project was able to be deployed successfully.
#JoinColumns({
#JoinColumn(name = "instrument_code_type", referencedColumnName = "code_type", insertable = false, updatable = false),
#JoinColumn(name = "instrument_id", referencedColumnName = "id", insertable = false, updatable = false)})
private InstrumentCodeType instrumentCodeType1;
private Instrument instrument;
It was here that I started to see what the problem might be:
https://access.redhat.com/site/documentation/en-US/JBoss_Enterprise_Application_Platform/5/html/Hibernate_Annotations_Reference_Guide/ch02s02s06.html
I suspect that my next problem will be something to do with the fact that the composite primary key is made up of columns from two different entities - instrument and instrumentCodeType. But for now the above change got me past the build problem and if that next problem arises I'll deal with it separately.

Categories