JPA JP-QL-SELECT Befehl für Entities

rogerssocke

Mitglied
Hallo Leute,

ich benötige Hilfe bei einem JP-QL Select Befehl.
Egal wie ich es versucht habe, es kam immer das falsche Ergebnis heraus.
Aber erst mal zu meinen Daten, ich habe folgende Entities:

Java:
@NamedQueries( {
@NamedQuery(name="modulColumn.findByModulName", query="SELECT a FROM ModulColumn AS a WHERE a.modulName = :modul_name"),
@NamedQuery(name="modulColumn.findByModulNameAndUser", 
		query="SELECT a FROM ModulColumn AS a " + "LEFT JOIN a.userModulColumns um " + 
		"LEFT JOIN um.loginUser as u " + 
		"WHERE a.modulName = :modul_name AND (um IS NULL OR u.name = :user_name)")
} )
@Entity
@Table(name="modul_column")
public class ModulColumn implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@SequenceGenerator(name="MODUL_COLUMN_ID_GENERATOR", sequenceName="MODUL_COLUMN_ID_SEQ")
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="MODUL_COLUMN_ID_GENERATOR")
	@Column(unique=true, nullable=false)
	private Integer id;

	@Column(name="db_column", nullable=false, length=2147483647)
	private String dbColumn;

	@Column(name="default_filter_typ", nullable=false)
	@Enumerated(EnumType.ORDINAL)
	private FieldTyp defaultFilterTyp;

	@Column(name="default_filter_value_1", length=2147483647)
	private String defaultFilterValue1;

	@Column(name="default_filter_value_2", length=2147483647)
	private String defaultFilterValue2;

	@Column(name="default_visible", nullable=false)
	private Boolean defaultVisible;

	@Column(name="db_table_name", nullable=false, length=2147483647)
	private String dbTableName;

	@Column(name="modul_name", nullable=false, length=2147483647)
	private String modulName;
	
	@Column(name="key_name", nullable=false, length=2147483647)
	private String keyName;

	@Column(nullable=false)
	@Version
	private Long version;

	//bi-directional many-to-one association to UserModulColumn
	@OneToOne(mappedBy="modulColumn")
	private UserModulColumn userModulColumns;

    public ModulColumn() {
    }

	public Integer getId() {
		return this.id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getDbColumn() {
		return this.dbColumn;
	}

	public void setDbColumn(String dbColumn) {
		this.dbColumn = dbColumn;
	}

	public FieldTyp getDefaultFilterTyp() {
		return this.defaultFilterTyp;
	}

	public void setDefaultFilterTyp(FieldTyp defaultFilterTyp) {
		this.defaultFilterTyp = defaultFilterTyp;
	}

	public String getDefaultFilterValue1() {
		return this.defaultFilterValue1;
	}

	public void setDefaultFilterValue1(String defaultFilterValue1) {
		this.defaultFilterValue1 = defaultFilterValue1;
	}

	public String getDefaultFilterValue2() {
		return this.defaultFilterValue2;
	}

	public void setDefaultFilterValue2(String defaultFilterValue2) {
		this.defaultFilterValue2 = defaultFilterValue2;
	}

	public Boolean getDefaultVisible() {
		return this.defaultVisible;
	}

	public void setDefaultVisible(Boolean defaultVisible) {
		this.defaultVisible = defaultVisible;
	}

	public String getDbTableName() {
		return this.dbTableName;
	}

	public void setDBTableName(String dbTableName) {
		this.dbTableName = dbTableName;
	}
	
	public String getKeyName() {
		return this.keyName;
	}

	public void setKeyName(String keyName) {
		this.keyName = keyName;
	}

	public String getModulName() {
		return this.modulName;
	}

	public void setModulName(String modulName) {
		this.modulName = modulName;
	}

	public Long getVersion() {
		return this.version;
	}

	public void setVersion(Long version) {
		this.version = version;
	}

	public UserModulColumn getUserModulColumns() {
		return this.userModulColumns;
	}

	public void setUserModulColumns(UserModulColumn userModulColumns) {
		this.userModulColumns = userModulColumns;
	}

Java:
@NamedQuery(name="userModulColumn.findByModulNameAndUser", query="SELECT a FROM UserModulColumn AS a" + " JOIN a.loginUser as u JOIN a.modulColumn as m " + " WHERE  m.modulName = :modul_name AND u.name = :user_name")
@Entity
@Table(name="user_modul_column")
public class UserModulColumn implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@SequenceGenerator(name="USER_MODUL_COLUMN_ID_GENERATOR", sequenceName="user_modul_column_id_seq", allocationSize=1)
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="USER_MODUL_COLUMN_ID_GENERATOR")
	@Column(unique=true, nullable=false)
	private Integer id;

	@Column(name="filter_typ")
	@Enumerated(EnumType.ORDINAL)
	private FieldTyp filterTyp;

	@Column(name="filter_value_2", length=2147483647)
	private String filterValue2;

	@Column(name="fitler_value_1", length=2147483647)
	private String fitlerValue1;

	@Column(nullable=false)
	@Version
	private Long version;

	private Boolean visible;

	//bi-directional many-to-one association to LoginUser
    @ManyToOne
	@JoinColumn(name="user_id", nullable=false)
	private LoginUser loginUser;

	//bi-directional many-to-one association to ModulColumn
    @OneToOne
	@JoinColumn(name="modul_column_id", nullable=false)
	private ModulColumn modulColumn;

    public UserModulColumn() {
    }

	public Integer getId() {
		return this.id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public FieldTyp getFilterTyp() {
		return this.filterTyp;
	}

	public void setFilterTyp(FieldTyp filterTyp) {
		this.filterTyp = filterTyp;
	}

	public String getFilterValue2() {
		return this.filterValue2;
	}

	public void setFilterValue2(String filterValue2) {
		this.filterValue2 = filterValue2;
	}

	public String getFitlerValue1() {
		return this.fitlerValue1;
	}

	public void setFitlerValue1(String fitlerValue1) {
		this.fitlerValue1 = fitlerValue1;
	}

	public Long getVersion() {
		return this.version;
	}

	public void setVersion(Long version) {
		this.version = version;
	}

	public Boolean getVisible() {
		return this.visible;
	}

	public void setVisible(Boolean visible) {
		this.visible = visible;
	}

	public LoginUser getLoginUser() {
		return this.loginUser;
	}

	public void setLoginUser(LoginUser loginUser) {
		this.loginUser = loginUser;
	}
	
	public ModulColumn getModulColumn() {
		return this.modulColumn;
	}

	public void setModulColumn(ModulColumn modulColumn) {
		this.modulColumn = modulColumn;
	}

Ich möchte mit diesen Entities die Feldauswahl für eine JTable je nach Modul und Benutzer in der Datenbank abspeichern.
Dafür habe ich mir überlegt ich mache eine Default-Auswahl welche ich in modulColumn abspeichere. Möchte ein User diesen Default Wert verändern, wird ein UserModulColumn angelegt.

Ich möchte jetzt über einen SELECT dem ich den Username und den Modulname übergebe die Default-Feldauswahl in Form einer List<ModulColumn> erhalten und falls ein User Anpassungen an der Feldauswahl gemacht hat sollen diese in ModulColumn.userModulColumn stehen.

Ich habe das ganze über folgende NamedQuery versucht "modulColumn.findByModulNameAndUser" (zu finden in der ModulColumn Entity). Allerdings habe ich dort den Nachteil, dass falls ich ein User selektiere der keine Feldauswahl gemacht hat und selektiere ich nur Spalten zurück bekomme die auch kein anderer User verändert hat. Steht eine Spalte in der UserModulColumn, dann wird diese auch nur noch bei diesem User angezeigt und bei keinem anderen.

Über JDBC habe ich mir folgenden SQL-Befehl überlegt, der allerdings nur mit JDBC funktioniert. Bei einer NATIVEQuery funktioniert dieser nicht richtig, da auch falls nichts gejoned wird die UserModulColumn von einem anderen USER gemapped wird. Der sah wie folgt aus:

Java:
StringBuffer buffer = new StringBuffer();
		buffer.append("SELECT ");
		buffer.append("a.id, a.modul_name, a.db_column, a.db_table_name, a.default_visible, a.default_filter_typ, a.default_filter_value_1, a.default_filter_value_2, a.version, a.key_name, ");
		buffer.append(" um.id, um.user_id, um.modul_column_id, um.visible, um.filter_typ, um.fitler_value_1, um.filter_value_2, um.version");
		buffer.append(" FROM modul_column AS a");
		buffer.append(" LEFT JOIN");
		buffer.append("(");
		buffer.append(" SELECT um.id, um.user_id, um.modul_column_id, um.visible, um.filter_typ, um.fitler_value_1, um.filter_value_2, um.version FROM user_modul_column AS um JOIN");
		buffer.append(" login_user u ON u.id = um.user_id");
		buffer.append(" WHERE u.name=:user_name");
		buffer.append(" )");
		buffer.append(" AS um");
		buffer.append(" ON um.modul_column_id = a.id");
		buffer.append(" WHERE a.modul_name=:modul_name");
		Query query = em.createNativeQuery(buffer.toString(), ModulColumn.class);
		query.setParameter("modul_name", modulName);
		query.setParameter("user_name", userName);
		return query.getResultList();

Wird bei diesem NativeQuery als Username ein Name übergeben, der nicht existiert, ist das UserModulColumn trotzdem belegt, falls es dazu einen anderen User gibt.

Was mache ich da falsch?
 

DanZ

Bekanntes Mitglied
Das Problem liegt denke ich in deinem Model: Was passiert denn wenn mehrere User eine Column verändert haben? In der Entity ModulColumn ist nur eine OneToOne-Association definiert. Ich vermute du legst die ModulColumn nur einmal an und nicht für jeden User neu(sonst würde die Query funktionieren).
Du könntest zum eine Many-To-One in Form einer List<UserModulColumn> in der der ModulColumn verwenden. Dann müsstest du aber immer über die Liste iterieren um festzustellen, ob der momentane User den Defaultwert verändert hat.
Eine andere Alternative wäre in diesem Fall eventuell Polymorphie.
 
Ähnliche Java Themen

Ähnliche Java Themen


Oben